线性移位寄存序列密码破译
2017-12-27 21:56
246 查看
目的:
对于线性移位寄存器产生的序列密码其核心是破译出其移位寄存器的数学表达式
移位寄存器产生序列密码原理:
对于对于移位寄存器的每一个储存格提供一个初始值,然后通过g0-加-gn的开关进行控制,哪几位进行模2加处理。每进行一次运算后,值向右移动一位,同时生成的新值作为新的输入数据进行输入。反复迭代,得到一连串的加密字节流。
已知条件:
100位由线性移位寄存器产生的连续连续字节流
破译过程
移位寄存器的函数GF(arrange,init):
输入:arrange移位寄存器的向量表达式,init移位寄存器的状态
输出:移位寄存器产生的值
说明:若线性移位寄存器具有实际意义,则其首项与末项均不能为0
代码实现如下:
因为移位寄存器每进行一次后其状态就会改变,所以再写一个函数,调用GF函数,来实现其多次迭代运算。
多次迭代移位寄存器的函数make_list(freq, arrange, init):
输入:freq为迭代的次数,arrange移位寄存器的向量表达式,init移位寄存器的最初始状态
输出:进过freq次迭代后产生的字节流
代码实现如下:
通过穷举来破译初始的字节流
一般来说,是n位的移位寄存器则前n位字节流可以作为移位寄存器的初始状态产生后续的字节流,而n位的移位寄存器其开关存在2的n-1次方种开关状态,所以移位寄存器的可能存在n*2^(n-1)种,通过穷举来寻找正确的移位寄存器状态。
解密函数decry(cry_string):
输入:加密后的字节流
输出:移位寄存器的状态
说明1:最大移位寄存器的位数为17位,最小位数为4位,可以通过maxlen进行设置,随着位数的提高,破译需要的时间呈指数增长。因为字节流内可能存在错误的字节,所以只需要匹配时正确的个数>=95即算找到了正确的寄存器开关状态。
说明2:通过十进制转二进制实现开关状态的控制
代码实现如下
模2加函数decry(cry_string):
输入:进行模2加的两个字节
输出:模2加结果
说明:字节相同则返回0,不同则返回1
对于线性移位寄存器产生的序列密码其核心是破译出其移位寄存器的数学表达式
移位寄存器产生序列密码原理:
对于对于移位寄存器的每一个储存格提供一个初始值,然后通过g0-加-gn的开关进行控制,哪几位进行模2加处理。每进行一次运算后,值向右移动一位,同时生成的新值作为新的输入数据进行输入。反复迭代,得到一连串的加密字节流。
已知条件:
100位由线性移位寄存器产生的连续连续字节流
破译过程
移位寄存器的函数GF(arrange,init):
输入:arrange移位寄存器的向量表达式,init移位寄存器的状态
输出:移位寄存器产生的值
说明:若线性移位寄存器具有实际意义,则其首项与末项均不能为0
代码实现如下:
def GF(arrange,init): #arrange为移位寄存器的开关状态 #init为移位寄存器的初始状态 #保证g0 和 gn不为0 assert arrange[0] == 1 assert arrange[-1] == 1 # 得出移位寄存器的阶数 n = len(arrange) - 1 #保证初始状态init的长度与阶数相等 assert len(init) == n #选择出进行mod2加的初始数字 mod_list = [] for i in range(n): if arrange[i] == 1: mod_list.append(init[i]) #这里需要保证不能全为0,不然无法进行mod2加 m = mod_list[0] for j in range(1,len(mod_list)): m = mod2add(m, mod_list[j]) return m
因为移位寄存器每进行一次后其状态就会改变,所以再写一个函数,调用GF函数,来实现其多次迭代运算。
多次迭代移位寄存器的函数make_list(freq, arrange, init):
输入:freq为迭代的次数,arrange移位寄存器的向量表达式,init移位寄存器的最初始状态
输出:进过freq次迭代后产生的字节流
代码实现如下:
def make_list(freq, arrange, init): string = '' #这里为了防止内存的被删除 new_init = [] for i in init: new_init.append(i) for i in new_init: string += str(i) for i in range(freq): result = GF(arrange, new_init) string += str(result) del new_init[0] new_init.append(result) del new_init return string
通过穷举来破译初始的字节流
一般来说,是n位的移位寄存器则前n位字节流可以作为移位寄存器的初始状态产生后续的字节流,而n位的移位寄存器其开关存在2的n-1次方种开关状态,所以移位寄存器的可能存在n*2^(n-1)种,通过穷举来寻找正确的移位寄存器状态。
解密函数decry(cry_string):
输入:加密后的字节流
输出:移位寄存器的状态
说明1:最大移位寄存器的位数为17位,最小位数为4位,可以通过maxlen进行设置,随着位数的提高,破译需要的时间呈指数增长。因为字节流内可能存在错误的字节,所以只需要匹配时正确的个数>=95即算找到了正确的寄存器开关状态。
说明2:通过十进制转二进制实现开关状态的控制
代码实现如下
def decry(cry_string): maxlen = 17 cry_list = [] for ab in cry_string: cry_list.append(ab) for rank in range(4, maxlen+1): init = cry_list[:rank] arrange = numpy.zeros((rank+1, 1)) arrange[0] = 1 arrange[-1] = 1 assert rank == len(bin(2**(rank-1)).replace('0b','')) for i in range(2**(rank-1)+1,2**rank): bin_arr = bin(i).replace('0b','') for j in range(len(bin_arr)): arrange[j] = int(bin_arr[j]) string = make_list(100-rank, arrange, init) print("此时的rank:",rank) print("产生的string为:",string) print("") flag = 0 count = 0 for i in range(len(cry_string)): if cry_string[i] == string[i]: count += 1 if count>95: flag = 1 print("破译结果为:",arrange) return 1 9492 if flag == 0: print("%d以内无法破译"%maxlen) return 0
模2加函数decry(cry_string):
输入:进行模2加的两个字节
输出:模2加结果
说明:字节相同则返回0,不同则返回1
def mod2add(a, b): if a == b: return '0' else: return '1'
相关文章推荐
- JXCELL实例学习与研究(四) 之 录入数据、绘制表格、修整线性表的颜色 密码的设置与破译
- 时间序列专题之三 时间序列的分段线性表示
- 使用MD5变换算法防穷举破译密码
- 02-线性结构1 两个有序链表序列的合并 (15分)
- HDOJ---1257 最少拦截系统[线性DP]+NYOJ---拦截导弹[输出最长单调子序列的长度]
- 北大ACM poj3749 破译密码
- 02-线性结构1 两个有序链表序列的合并 (15分)
- BZOJ 5043: 密码破译 dp
- poj 3749 破译密码
- 求解最大子序列和问题的线性时间算法
- 网上出现340-cipher破解系统 邀请大家一起破译Zodiac密码
- bzoj5043 密码破译
- 崮云湖街道:“钉钉子”精神破译发展密码
- 杭电1287破译密码
- Python序列循环移位的3种方法推荐
- 线性选择序列第k小 / 中位数附近k个数
- 02-线性结构1 两个有序链表序列的合并
- 几种线性DP(最长上升子序列,最长公共子序列等)
- [续]c#凯撒密码破译的原理与实现
- 第十周 项目二 小刚破译加密密码