Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 选择字符串作为随机种子对输出的影响_Python_Python 2.7_Cryptography_Permutation - Fatal编程技术网

Python 选择字符串作为随机种子对输出的影响

Python 选择字符串作为随机种子对输出的影响,python,python-2.7,cryptography,permutation,Python,Python 2.7,Cryptography,Permutation,在python中,为了排列字符串的letter,可以编写 import random random.seed(str_key) length = range(len(original_str)) random.shuffle(length) join "".join([original_key[idx] for idx in length]) 我想知道seed对键字符串做了什么,以及它如何从中产生置换(或者说shuffle如何做到这一点)。例如,如果我将键设为“hGd”,那么我如何获得特定的输

在python中,为了排列字符串的letter,可以编写

import random
random.seed(str_key)
length = range(len(original_str))
random.shuffle(length)
join "".join([original_key[idx] for idx in length])
我想知道seed对键字符串做了什么,以及它如何从中产生置换(或者说shuffle如何做到这一点)。例如,如果我将键设为“hGd”,那么我如何获得特定的输出,而如果我编写另一个键,如“AGd”,则会获得另一个输出

编辑:我尝试在该代码上使用的解密算法是:

for key in itertools.product(*3*[string.ascii_letters]):
    indices = range(len(enc_msg))
    list_encrypted_msg = list(enc_msg)
    random.seed(key)
    random.shuffle(indices)
    decrypted = ""

    for idx in indices[::-1]:
        decrypted += list_encrypted_msg[idx]

    try:
        if not decrypted.index("The"):
            print decrypted
    except ValueError:
        continue
return "not found!"
seed()
对其参数所做的是将其传递给内置的
hash()
函数,该函数将其转换为32位有符号整数,即范围为-2147483648到2147483647的数字。然后,作为标准随机函数核心的伪随机整数生成器(默认情况下,Mersenne Twister算法)将该数字用作起始数字

每次调用伪随机数生成器(PRNG)时,它都会对其当前数执行特定的算术运算以生成新数。它可以按原样返回该数字,也可以返回该数字的修改版本。有关简单类型的PRNG,请参阅

有了好的PRNG,很难预测序列中的下一个数字是什么,Mersenne Twister非常好。因此,预测不同种子对产量的影响并不容易

顺便说一句,您可以传递任何类型的哈希对象。因此,它可以被传递一个int、字符串、元组等,但不能传递一个列表。但正如我上面所说的,无论你通过什么,它都会被转换成一个数字

更新在Python的最新版本中,采用可选版本arg version 1的工作方式与我前面描述的相同,但是version 2(Python 3.2+中的默认版本)a
str
bytes
bytearray
对象被转换为
int
,并使用其所有位

我想我应该提到,如果调用
seed()
时没有种子值,它会使用池来生成种子值,如果系统没有提供熵池,则当前时间作为其种子值


Mersenne Twister算法的周期为
2**19937-1
,约为6000位十进制数字。因此,它产生的整数循环需要很长时间才能准确地重复。当然,单个整数和整数的子序列将更快地重复。Python版本的Mersenne Twister实际上并不返回它计算的整数,而是将它们转换为53位浮点数;我假设它在内部使用64位。如果您想知道它是如何工作的,请参阅维基百科上的文章

FWIW,这里有一个稍微改进的程序版本

import random

#Convert string to list
msg = list(original_str)

random.seed(str_key)
random.shuffle(msg)
print "".join(msg)

现在,谈谈您的解密问题。:)您必须解密的消息是否只是像上面的程序那样被加扰,还是使用了其他形式的加密?如果它仅仅是乱码,那么解读起来就相对容易了。因此,除非你告诉我其他情况,否则我将假设情况就是这样

你说过键的长度是3。键是纯字母,还是键中的3个字符可以是chr(0)到chr(255)范围内的任何字符?无论哪种方式,都没有太多的键需要检查,Python程序将能够在不到一秒钟的时间内使用蛮力搜索所有键来解读消息


要迭代所有可能的键,可以执行以下操作:

from itertools import product
from string import ascii_letters

for k in product(*3*[ascii_letters]):
    str_key = ''.join(k)
我在代码中使用了
product()
,因为我们想要生成所有可能的3个ascii字母的字符串,所以我们想要3个
ascii字母的笛卡尔乘积
3*[ascii字母]
相当于
[ascii字母,ascii字母,ascii字母]
,将
*
放在前面会打开该列表,这样
product()
会得到3个单独的参数。如果我们使用
permutations()
,那么就不会得到任何包含重复字符的字符串。举例说明:

>>> import itertools
>>> s='abc'
>>> [''.join(u) for u in itertools.permutations(s, 3)]
['abc', 'acb', 'bac', 'bca', 'cab', 'cba']
>>> [''.join(u) for u in itertools.product(*3*[s])]
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 
 'baa', 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 
 'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']
Update采用repeat关键字arg,因此我们可以将其简化为
itertools.product(s,repeat=3)

我记得你说过要解码的字符串有42个字符,但在
euTtSa:0 kty1h a0 nlradstara atlot 5wtic
中只有40个字符。此外,该字符串中数字
0
&
5
的出现也有点令人担忧,尽管我猜原始未解读版本中可能有数字

不管怎么说,我只是试着用所有可能的140608 3字母键,用洗牌算法来解读这个字符串,然后打印以
开头的排列。其中只有5个,其中只有一个在
后面有空格。但在任何情况下,未解读字符串的其余部分都是垃圾。我猜你误解了讲师使用的加密算法


如果您想知道random.shuffle()的工作原理,您可以看到与实际C源代码等效的Python代码。这就像一次通过选择排序的随机版本

另一个可爱的方法是使用随机比较函数或随机键函数对列表进行排序。乙二醇

>>> import random
>>> random.seed(42)
>>> for i in range(10):
...   s.sort(key=lambda i:random.random())
...   print ''.join(s)
...
gabecdf
dbgfeac
agbfdce
cebdgaf
fgedbca
afbecgd
bcaegfd
aebcdfg
bacgfed
fgdebca
但是,
random.shuffle()
使用的技术更高效,速度更快,因为它完全是用C实现的


反转给定密钥的洗牌过程 让我们看看当我们洗牌一个简单的范围时会发生什么

from random import seed, shuffle

r = range(5)
key = 'zap'
seed(key)
shuffle(r) 
洗牌后,
r

[2,4,1,3,0]

因此,要取消缓冲
r
,我们需要建立以下列表:

[r[4]、r[2]、r[0]、r[3]、r[1]

你知道怎么做吗?如果你不能理解,我很乐意发布我的代码,但我认为你应该先花一点时间尝试理解它。提示:不要试图在列表理解中执行此操作,只需使用
for
循环即可


#! /usr/bin/env python ''' Unscramble a string of text by brute force From http://stackoverflow.com/questions/26248379/influence-of-choosing-string-as-seed-of-random-on-the-output ''' import sys from random import seed, shuffle from itertools import product from string import ascii_letters def scramble(seq, key): seed(key) msg = seq[:] shuffle(msg) return msg def scramble_old(seq, key): seed(key) r = range(len(seq)) shuffle(r) return [seq[i] for i in r] def unscramble(seq, key): seed(key) r = range(len(seq)) shuffle(r) newseq = len(seq) * [None] for i, j in enumerate(r): newseq[j] = seq[i] return newseq def test(): key = 'zap' #orig = 'quickbrownfox' orig = '01234' print 'orig: ', orig shuf = scramble(list(orig), key) print 'shuffled: ', ''.join(shuf) unshuf = unscramble(shuf, key) print 'unshuffled: ', ''.join(unshuf) def decode(seq, begin): count = 0 begin_len = len(begin) for k in product(*3*[ascii_letters]): key = ''.join(k) dup = seq[:] newseq = unscramble(dup, key) if newseq[:begin_len] == begin: count += 1 print '%s: [%s] %s' % (key, ''.join(newseq), count) #print ' [%s]\n' % ''.join(scramble(newseq, key)) def main(): original_str = 'euTtSa:0 kty1h a0 nlradstara atlot 5wtic'.lower() original_list = list(original_str) print ' [%s], %d\n' % (original_str, len(original_str)) decode(original_list, begin=list('the')) if __name__ == '__main__': #test() main()