Skip to main content
 首页 » 编程设计

python之重构这个分组密码键控函数

2025年05月04日9thcjp

我找到了一个简单的纯 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。它也重复这些数字,而不是而不是将其视为单个大数。您应该检查此代码是否实际执行了正确的算法。