我找到了一个简单的纯 python blowfish 实现,可以满足我对特定项目的需求。
其中只有一部分困扰着我:
def initialize(key):
"""
Use key to setup subkeys -- requires 521 encryptions
to set p and s boxes. key is a hex number corresponding
to a string of 32 up to 448 1s and 0s -- keylen says
how long
"""
# Note that parray and sboxes are globals that have been pre-initialized.
hexkey = hex(key)[2:]
if hexkey[-1]=='L':
hexkey = hexkey[:-1]
if len(hexkey)%2==1:
hexkey = '0'+hexkey
lenkey = len(hexkey)/8
if lenkey==0:
pos=0
# XOR key segments with P-boxes
for i in range(18):
if lenkey>0:
pos = (i%lenkey)*8 # offset into key gives subkey
subkey = eval('0x'+hexkey[pos:pos+8]+'L')
parray[i] ^= subkey # immediate XOR -- Python 2.0+ syntax
# encrypt 0-data, then keep re-encrypting and reassigning P-boxes
output = 0L
for i in range(0,17,2):
output = bfencrypt(output)
parray[i], parray[i+1] = output>>32, output & 0xFFFFFFFFL
# re-encrypt and reassign through all the S-boxes
for i in range(4):
for j in range(0,255,2):
output = bfencrypt(output)
sbox[i][j],sbox[i][j+1] = output>>32, output & 0xFFFFFFFFL
# print "Initialization complete"
subkey = eval('0x'+hexkey[pos:pos+8]+'L')
?请告诉我有更好的方法来做到这一点。
有没有办法重构它以使用实际的整数类型而不是字符串中的十六进制值?
最佳答案
是的。使用基数为 16 的 int()。
>>> int('ffffffff',16)
4294967295L
所以:
subkey = int(hexkey[pos:pos+8], 16)
应该不需要评估就可以做同样的事情。
[编辑] 事实上,给定一个整数,通常根本没有理由需要转换为字符串表示形式 - 您可以通过与0xffffffff
并在循环中将 key 右移 32 位。例如:
subkeys = []
while key:
subkeys.append(key & 0xffffffff)
key >>= 32
if not subkeys: subkeys = [0] # Handle 0 case
subkeys.reverse() # Use same order as before (BUT SEE BELOW)
但是,这个初始化过程似乎有点奇怪 - 它使用从左边开始的十六进制数字,没有零填充来舍入到 8 个十六进制数字的倍数(因此数字 0x123456789
将是分成0x12345678
和0x9
,而不是更习惯的0x00000001
和0x23456789
。它也重复这些数字,而不是而不是将其视为单个大数。您应该检查此代码是否实际执行了正确的算法。
关于python - 重构这个分组密码键控函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/996965/