S_BOX = [ 0x63 , 0x7C , 0x77 , 0x7B , 0xF2 , 0x6B , 0x6F , 0xC5 , 0x30 , 0x01 , 0x67 , 0x2B , 0xFE , 0xD7 , 0xAB , 0x76 , 0xCA , 0x82 , 0xC9 , 0x7D , 0xFA , 0x59 , 0x47 , 0xF0 , 0xAD , 0xD4 , 0xA2 , 0xAF , 0x9C , 0xA4 , 0x72 , 0xC0 , 0xB7 , 0xFD , 0x93 , 0x26 , 0x36 , 0x3F , 0xF7 , 0xCC , 0x34 , 0xA5 , 0xE5 , 0xF1 , 0x71 , 0xD8 , 0x31 , 0x15 , 0x04 , 0xC7 , 0x23 , 0xC3 , 0x18 , 0x96 , 0x05 , 0x9A , 0x07 , 0x12 , 0x80 , 0xE2 , 0xEB , 0x27 , 0xB2 , 0x75 , 0x09 , 0x83 , 0x2C , 0x1A , 0x1B , 0x6E , 0x5A , 0xA0 , 0x52 , 0x3B , 0xD6 , 0xB3 , 0x29 , 0xE3 , 0x2F , 0x84 , 0x53 , 0xD1 , 0x00 , 0xED , 0x20 , 0xFC , 0xB1 , 0x5B , 0x6A , 0xCB , 0xBE , 0x39 , 0x4A , 0x4C , 0x58 , 0xCF , 0xD0 , 0xEF , 0xAA , 0xFB , 0x43 , 0x4D , 0x33 , 0x85 , 0x45 , 0xF9 , 0x02 , 0x7F , 0x50 , 0x3C , 0x9F , 0xA8 , 0x51 , 0xA3 , 0x40 , 0x8F , 0x92 , 0x9D , 0x38 , 0xF5 , 0xBC , 0xB6 , 0xDA , 0x21 , 0x10 , 0xFF , 0xF3 , 0xD2 , 0xCD , 0x0C , 0x13 , 0xEC , 0x5F , 0x97 , 0x44 , 0x17 , 0xC4 , 0xA7 , 0x7E , 0x3D , 0x64 , 0x5D , 0x19 , 0x73 , 0x60 , 0x81 , 0x4F , 0xDC , 0x22 , 0x2A , 0x90 , 0x88 , 0x46 , 0xEE , 0xB8 , 0x14 , 0xDE , 0x5E , 0x0B , 0xDB , 0xE0 , 0x32 , 0x3A , 0x0A , 0x49 , 0x06 , 0x24 , 0x5C , 0xC2 , 0xD3 , 0xAC , 0x62 , 0x91 , 0x95 , 0xE4 , 0x79 , 0xE7 , 0xC8 , 0x37 , 0x6D , 0x8D , 0xD5 , 0x4E , 0xA9 , 0x6C , 0x56 , 0xF4 , 0xEA , 0x65 , 0x7A , 0xAE , 0x08 , 0xBA , 0x78 , 0x25 , 0x2E , 0x1C , 0xA6 , 0xB4 , 0xC6 , 0xE8 , 0xDD , 0x74 , 0x1F , 0x4B , 0xBD , 0x8B , 0x8A , 0x70 , 0x3E , 0xB5 , 0x66 , 0x48 , 0x03 , 0xF6 , 0x0E , 0x61 , 0x35 , 0x57 , 0xB9 , 0x86 , 0xC1 , 0x1D , 0x9E , 0xE1 , 0xF8 , 0x98 , 0x11 , 0x69 , 0xD9 , 0x8E , 0x94 , 0x9B , 0x1E , 0x87 , 0xE9 , 0xCE , 0x55 , 0x28 , 0xDF , 0x8C , 0xA1 , 0x89 , 0x0D , 0xBF , 0xE6 , 0x42 , 0x68 , 0x41 , 0x99 , 0x2D , 0x0F , 0xB0 , 0x54 , 0xBB , 0x16
] RCON = [ 0x00 , 0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40 , 0x80 , 0x1B , 0x36
] def sub_bytes ( state) : for i in range ( 4 ) : for j in range ( 4 ) : state[ i] [ j] = S_BOX[ state[ i] [ j] ] def shift_rows ( state) : state[ 1 ] = state[ 1 ] [ 1 : ] + state[ 1 ] [ : 1 ] state[ 2 ] = state[ 2 ] [ 2 : ] + state[ 2 ] [ : 2 ] state[ 3 ] = state[ 3 ] [ 3 : ] + state[ 3 ] [ : 3 ] def xtime ( a) : return ( ( a << 1 ) ^ 0x1B ) & 0xFF if a & 0x80 else a << 1 def mix_single_column ( a) : t = a[ 0 ] ^ a[ 1 ] ^ a[ 2 ] ^ a[ 3 ] u = a[ 0 ] a[ 0 ] ^ = t ^ xtime( a[ 0 ] ^ a[ 1 ] ) a[ 1 ] ^ = t ^ xtime( a[ 1 ] ^ a[ 2 ] ) a[ 2 ] ^ = t ^ xtime( a[ 2 ] ^ a[ 3 ] ) a[ 3 ] ^ = t ^ xtime( a[ 3 ] ^ u) def mix_columns ( state) : for i in range ( 4 ) : col = [ state[ row] [ i] for row in range ( 4 ) ] mix_single_column( col) for row in range ( 4 ) : state[ row] [ i] = col[ row] def add_round_key ( state, round_key) : for i in range ( 4 ) : for j in range ( 4 ) : state[ i] [ j] ^ = round_key[ i] [ j] def key_expansion ( key) : expanded = [ key[ i: i+ 4 ] for i in range ( 0 , 16 , 4 ) ] for i in range ( 4 , 44 ) : word = expanded[ i- 1 ] [ : ] if i % 4 == 0 : word = word[ 1 : ] + word[ : 1 ] word = [ S_BOX[ b] for b in word] word[ 0 ] ^ = RCON[ i// 4 ] expanded. append( [ expanded[ i- 4 ] [ j] ^ word[ j] for j in range ( 4 ) ] ) return [ expanded[ 4 * i: 4 * ( i+ 1 ) ] for i in range ( 11 ) ] def encrypt_block ( plain, key_schedule) : state = [ plain[ i: i+ 4 ] for i in range ( 0 , 16 , 4 ) ] add_round_key( state, key_schedule[ 0 ] ) for rnd in range ( 1 , 10 ) : sub_bytes( state) shift_rows( state) mix_columns( state) add_round_key( state, key_schedule[ rnd] ) sub_bytes( state) shift_rows( state) add_round_key( state, key_schedule[ 10 ] ) return [ byte for row in state for byte in row] def AES_encrypt ( plaintext, key) : assert len ( plaintext) == 16 and len ( key) == 16 , "Plaintext and key must be 16 bytes." key_schedule = key_expansion( key) ciphertext = encrypt_block( plaintext, key_schedule) return ciphertext'''
AES 解密算法
'''
INV_S_BOX = [ 0x52 , 0x09 , 0x6A , 0xD5 , 0x30 , 0x36 , 0xA5 , 0x38 , 0xBF , 0x40 , 0xA3 , 0x9E , 0x81 , 0xF3 , 0xD7 , 0xFB , 0x7C , 0xE3 , 0x39 , 0x82 , 0x9B , 0x2F , 0xFF , 0x87 , 0x34 , 0x8E , 0x43 , 0x44 , 0xC4 , 0xDE , 0xE9 , 0xCB , 0x54 , 0x7B , 0x94 , 0x32 , 0xA6 , 0xC2 , 0x23 , 0x3D , 0xEE , 0x4C , 0x95 , 0x0B , 0x42 , 0xFA , 0xC3 , 0x4E , 0x08 , 0x2E , 0xA1 , 0x66 , 0x28 , 0xD9 , 0x24 , 0xB2 , 0x76 , 0x5B , 0xA2 , 0x49 , 0x6D , 0x8B , 0xD1 , 0x25 , 0x72 , 0xF8 , 0xF6 , 0x64 , 0x86 , 0x68 , 0x98 , 0x16 , 0xD4 , 0xA4 , 0x5C , 0xCC , 0x5D , 0x65 , 0xB6 , 0x92 , 0x6C , 0x70 , 0x48 , 0x50 , 0xFD , 0xED , 0xB9 , 0xDA , 0x5E , 0x15 , 0x46 , 0x57 , 0xA7 , 0x8D , 0x9D , 0x84 , 0x90 , 0xD8 , 0xAB , 0x00 , 0x8C , 0xBC , 0xD3 , 0x0A , 0xF7 , 0xE4 , 0x58 , 0x05 , 0xB8 , 0xB3 , 0x45 , 0x06 , 0xD0 , 0x2C , 0x1E , 0x8F , 0xCA , 0x3F , 0x0F , 0x02 , 0xC1 , 0xAF , 0xBD , 0x03 , 0x01 , 0x13 , 0x8A , 0x6B , 0x3A , 0x91 , 0x11 , 0x41 , 0x4F , 0x67 , 0xDC , 0xEA , 0x97 , 0xF2 , 0xCF , 0xCE , 0xF0 , 0xB4 , 0xE6 , 0x73 , 0x96 , 0xAC , 0x74 , 0x22 , 0xE7 , 0xAD , 0x35 , 0x85 , 0xE2 , 0xF9 , 0x37 , 0xE8 , 0x1C , 0x75 , 0xDF , 0x6E , 0x47 , 0xF1 , 0x1A , 0x71 , 0x1D , 0x29 , 0xC5 , 0x89 , 0x6F , 0xB7 , 0x62 , 0x0E , 0xAA , 0x18 , 0xBE , 0x1B , 0xFC , 0x56 , 0x3E , 0x4B , 0xC6 , 0xD2 , 0x79 , 0x20 , 0x9A , 0xDB , 0xC0 , 0xFE , 0x78 , 0xCD , 0x5A , 0xF4 , 0x1F , 0xDD , 0xA8 , 0x33 , 0x88 , 0x07 , 0xC7 , 0x31 , 0xB1 , 0x12 , 0x10 , 0x59 , 0x27 , 0x80 , 0xEC , 0x5F , 0x60 , 0x51 , 0x7F , 0xA9 , 0x19 , 0xB5 , 0x4A , 0x0D , 0x2D , 0xE5 , 0x7A , 0x9F , 0x93 , 0xC9 , 0x9C , 0xEF , 0xA0 , 0xE0 , 0x3B , 0x4D , 0xAE , 0x2A , 0xF5 , 0xB0 , 0xC8 , 0xEB , 0xBB , 0x3C , 0x83 , 0x53 , 0x99 , 0x61 , 0x17 , 0x2B , 0x04 , 0x7E , 0xBA , 0x77 , 0xD6 , 0x26 , 0xE1 , 0x69 , 0x14 , 0x63 , 0x55 , 0x21 , 0x0C , 0x7D
] def inv_sub_bytes ( state) : for i in range ( 4 ) : for j in range ( 4 ) : state[ i] [ j] = INV_S_BOX[ state[ i] [ j] ] def inv_shift_rows ( state) : state[ 1 ] = state[ 1 ] [ - 1 : ] + state[ 1 ] [ : - 1 ] state[ 2 ] = state[ 2 ] [ - 2 : ] + state[ 2 ] [ : - 2 ] state[ 3 ] = state[ 3 ] [ - 3 : ] + state[ 3 ] [ : - 3 ] def inv_mix_single_column ( a) : u = xtime( xtime( a[ 0 ] ^ a[ 2 ] ) ) v = xtime( xtime( a[ 1 ] ^ a[ 3 ] ) ) a[ 0 ] ^ = ua[ 1 ] ^ = va[ 2 ] ^ = ua[ 3 ] ^ = vmix_single_column( a) def inv_mix_columns ( state) : for i in range ( 4 ) : col = [ state[ row] [ i] for row in range ( 4 ) ] inv_mix_single_column( col) for row in range ( 4 ) : state[ row] [ i] = col[ row] def decrypt_block ( cipher, key_schedule) : state = [ cipher[ i: i+ 4 ] for i in range ( 0 , 16 , 4 ) ] add_round_key( state, key_schedule[ 10 ] ) for rnd in range ( 9 , 0 , - 1 ) : inv_shift_rows( state) inv_sub_bytes( state) add_round_key( state, key_schedule[ rnd] ) inv_mix_columns( state) inv_shift_rows( state) inv_sub_bytes( state) add_round_key( state, key_schedule[ 0 ] ) return [ byte for row in state for byte in row] def AES_decrypt ( ciphertext, key) : key_schedule = key_expansion( key) plaintext = decrypt_block( ciphertext, key_schedule) return plaintextdef main ( ) : plaintext = [ 0x32 , 0x43 , 0xf6 , 0xa8 , 0x88 , 0x5a , 0x30 , 0x8d , 0x31 , 0x31 , 0x98 , 0xa2 , 0xe0 , 0x37 , 0x07 , 0x34 ] key = [ 0x2b , 0x7e , 0x15 , 0x16 , 0x28 , 0xae , 0xd2 , 0xa6 , 0xab , 0xf7 , 0x15 , 0x88 , 0x09 , 0xcf , 0x4f , 0x3c ] ciphertext = AES_encrypt( plaintext, key) ciphertext_hex = '' . join( '{:02x}' . format ( b) for b in ciphertext) print ( 'AES加密后的密文:' , ciphertext_hex) decrypted_text = AES_decrypt( ciphertext, key) decrypted_hex = '' . join( '{:02x}' . format ( b) for b in decrypted_text) print ( 'AES解密后的明文:' , decrypted_hex) if decrypted_text == plaintext: print ( ' 解密成功,明文与原始数据一致。' ) else : print ( ' 解密失败,明文与原始数据不一致。' ) if __name__ == '__main__' : main( )
IP = [ 58 , 50 , 42 , 34 , 26 , 18 , 10 , 2 , 60 , 52 , 44 , 36 , 28 , 20 , 12 , 4 , 62 , 54 , 46 , 38 , 30 , 22 , 14 , 6 , 64 , 56 , 48 , 40 , 32 , 24 , 16 , 8 , 57 , 49 , 41 , 33 , 25 , 17 , 9 , 1 , 59 , 51 , 43 , 35 , 27 , 19 , 11 , 3 , 61 , 53 , 45 , 37 , 29 , 21 , 13 , 5 , 63 , 55 , 47 , 39 , 31 , 23 , 15 , 7
] IP_INV = [ 40 , 8 , 48 , 16 , 56 , 24 , 64 , 32 , 39 , 7 , 47 , 15 , 55 , 23 , 63 , 31 , 38 , 6 , 46 , 14 , 54 , 22 , 62 , 30 , 37 , 5 , 45 , 13 , 53 , 21 , 61 , 29 , 36 , 4 , 44 , 12 , 52 , 20 , 60 , 28 , 35 , 3 , 43 , 11 , 51 , 19 , 59 , 27 , 34 , 2 , 42 , 10 , 50 , 18 , 58 , 26 , 33 , 1 , 41 , 9 , 49 , 17 , 57 , 25
] S_BOX = [ [ [ 14 , 4 , 13 , 1 , 2 , 15 , 11 , 8 , 3 , 10 , 6 , 12 , 5 , 9 , 0 , 7 ] , [ 0 , 15 , 7 , 4 , 14 , 2 , 13 , 1 , 10 , 6 , 12 , 11 , 9 , 5 , 3 , 8 ] , [ 4 , 1 , 14 , 8 , 13 , 6 , 2 , 11 , 15 , 12 , 9 , 7 , 3 , 10 , 5 , 0 ] , [ 15 , 12 , 8 , 2 , 4 , 9 , 1 , 7 , 5 , 11 , 3 , 14 , 10 , 0 , 6 , 13 ] , ] , [ [ 15 , 1 , 8 , 14 , 6 , 11 , 3 , 4 , 9 , 7 , 2 , 13 , 12 , 0 , 5 , 10 ] , [ 3 , 13 , 4 , 7 , 15 , 2 , 8 , 14 , 12 , 0 , 1 , 10 , 6 , 9 , 11 , 5 ] , [ 0 , 14 , 7 , 11 , 10 , 4 , 13 , 1 , 5 , 8 , 12 , 6 , 9 , 3 , 2 , 15 ] , [ 13 , 8 , 10 , 1 , 3 , 15 , 4 , 2 , 11 , 6 , 7 , 12 , 0 , 5 , 14 , 9 ] , ] , [ [ 10 , 0 , 9 , 14 , 6 , 3 , 15 , 5 , 1 , 13 , 12 , 7 , 11 , 4 , 2 , 8 ] , [ 13 , 7 , 0 , 9 , 3 , 4 , 6 , 10 , 2 , 8 , 5 , 14 , 12 , 11 , 15 , 1 ] , [ 13 , 6 , 4 , 9 , 8 , 15 , 3 , 0 , 11 , 1 , 2 , 12 , 5 , 10 , 14 , 7 ] , [ 1 , 10 , 13 , 0 , 6 , 9 , 8 , 7 , 4 , 15 , 14 , 3 , 11 , 5 , 2 , 12 ] , ] , [ [ 7 , 13 , 14 , 3 , 0 , 6 , 9 , 10 , 1 , 2 , 8 , 5 , 11 , 12 , 4 , 15 ] , [ 13 , 8 , 11 , 5 , 6 , 15 , 0 , 3 , 4 , 7 , 2 , 12 , 1 , 10 , 14 , 9 ] , [ 10 , 6 , 9 , 0 , 12 , 11 , 7 , 13 , 15 , 1 , 3 , 14 , 5 , 2 , 8 , 4 ] , [ 3 , 15 , 0 , 6 , 10 , 1 , 13 , 8 , 9 , 4 , 5 , 11 , 12 , 7 , 2 , 14 ] , ] , [ [ 2 , 12 , 4 , 1 , 7 , 10 , 11 , 6 , 8 , 5 , 3 , 15 , 13 , 0 , 14 , 9 ] , [ 14 , 11 , 2 , 12 , 4 , 7 , 13 , 1 , 5 , 0 , 15 , 10 , 3 , 9 , 8 , 6 ] , [ 4 , 2 , 1 , 11 , 10 , 13 , 7 , 8 , 15 , 9 , 12 , 5 , 6 , 3 , 0 , 14 ] , [ 11 , 8 , 12 , 7 , 1 , 14 , 2 , 13 , 6 , 15 , 0 , 9 , 10 , 4 , 5 , 3 ] , ] , [ [ 12 , 1 , 10 , 15 , 9 , 2 , 6 , 8 , 0 , 13 , 3 , 4 , 14 , 7 , 5 , 11 ] , [ 10 , 15 , 4 , 2 , 7 , 12 , 9 , 5 , 6 , 1 , 13 , 14 , 0 , 11 , 3 , 8 ] , [ 9 , 14 , 15 , 5 , 2 , 8 , 12 , 3 , 7 , 0 , 4 , 10 , 1 , 13 , 11 , 6 ] , [ 4 , 3 , 2 , 12 , 9 , 5 , 15 , 10 , 11 , 14 , 1 , 7 , 6 , 0 , 8 , 13 ] , ] , [ [ 4 , 11 , 2 , 14 , 15 , 0 , 8 , 13 , 3 , 12 , 9 , 7 , 5 , 10 , 6 , 1 ] , [ 13 , 0 , 11 , 7 , 4 , 9 , 1 , 10 , 14 , 3 , 5 , 12 , 2 , 15 , 8 , 6 ] , [ 1 , 4 , 11 , 13 , 12 , 3 , 7 , 14 , 10 , 15 , 6 , 8 , 0 , 5 , 9 , 2 ] , [ 6 , 11 , 13 , 8 , 1 , 4 , 10 , 7 , 9 , 5 , 0 , 15 , 14 , 2 , 3 , 12 ] , ] , [ [ 13 , 2 , 8 , 4 , 6 , 15 , 11 , 1 , 10 , 9 , 3 , 14 , 5 , 0 , 12 , 7 ] , [ 1 , 15 , 13 , 8 , 10 , 3 , 7 , 4 , 12 , 5 , 6 , 11 , 0 , 14 , 9 , 2 ] , [ 7 , 11 , 4 , 1 , 9 , 12 , 14 , 2 , 0 , 6 , 10 , 13 , 15 , 3 , 5 , 8 ] , [ 2 , 1 , 14 , 7 , 4 , 10 , 8 , 13 , 15 , 12 , 9 , 0 , 3 , 5 , 6 , 11 ] , ]
] def permute ( block, table) : return [ block[ i- 1 ] for i in table] def shift_left ( key_half, shifts) : return key_half[ shifts: ] + key_half[ : shifts] def xor ( bits1, bits2) : return [ b1 ^ b2 for b1, b2 in zip ( bits1, bits2) ] def sbox_substitution ( block48) : output = [ ] for i in range ( 8 ) : chunk = block48[ i* 6 : ( i+ 1 ) * 6 ] row = ( chunk[ 0 ] << 1 ) | chunk[ 5 ] col = ( chunk[ 1 ] << 3 ) | ( chunk[ 2 ] << 2 ) | ( chunk[ 3 ] << 1 ) | chunk[ 4 ] val = S_BOX[ i] [ row] [ col] bin_val = [ int ( b) for b in f' { val: 04b } ' ] output += bin_valreturn outputdef generate_subkeys ( key64) : PC1 = [ 57 , 49 , 41 , 33 , 25 , 17 , 9 , 1 , 58 , 50 , 42 , 34 , 26 , 18 , 10 , 2 , 59 , 51 , 43 , 35 , 27 , 19 , 11 , 3 , 60 , 52 , 44 , 36 , 63 , 55 , 47 , 39 , 31 , 23 , 15 , 7 , 62 , 54 , 46 , 38 , 30 , 22 , 14 , 6 , 61 , 53 , 45 , 37 , 29 , 21 , 13 , 5 , 28 , 20 , 12 , 4 ] PC2 = [ 14 , 17 , 11 , 24 , 1 , 5 , 3 , 28 , 15 , 6 , 21 , 10 , 23 , 19 , 12 , 4 , 26 , 8 , 16 , 7 , 27 , 20 , 13 , 2 , 41 , 52 , 31 , 37 , 47 , 55 , 30 , 40 , 51 , 45 , 33 , 48 , 44 , 49 , 39 , 56 , 34 , 53 , 46 , 42 , 50 , 36 , 29 , 32 ] SHIFT_SCHEDULE = [ 1 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 1 ] key56 = permute( key64, PC1) C, D = key56[ : 28 ] , key56[ 28 : ] subkeys = [ ] for shift in SHIFT_SCHEDULE: C, D = shift_left( C, shift) , shift_left( D, shift) subkey = permute( C + D, PC2) subkeys. append( subkey) return subkeysdef feistel ( R, subkey) : E = [ 32 , 1 , 2 , 3 , 4 , 5 , 4 , 5 , 6 , 7 , 8 , 9 , 8 , 9 , 10 , 11 , 12 , 13 , 12 , 13 , 14 , 15 , 16 , 17 , 16 , 17 , 18 , 19 , 20 , 21 , 20 , 21 , 22 , 23 , 24 , 25 , 24 , 25 , 26 , 27 , 28 , 29 , 28 , 29 , 30 , 31 , 32 , 1 ] P = [ 16 , 7 , 20 , 21 , 29 , 12 , 28 , 17 , 1 , 15 , 23 , 26 , 5 , 18 , 31 , 10 , 2 , 8 , 24 , 14 , 32 , 27 , 3 , 9 , 19 , 13 , 30 , 6 , 22 , 11 , 4 , 25 ] expanded_R = permute( R, E) xor_result = xor( expanded_R, subkey) substituted = sbox_substitution( xor_result) return permute( substituted, P) def DES_encrypt ( plaintext64, key64) : permuted_text = permute( plaintext64, IP) L, R = permuted_text[ : 32 ] , permuted_text[ 32 : ] subkeys = generate_subkeys( key64) for i in range ( 16 ) : temp_R = RR = xor( L, feistel( R, subkeys[ i] ) ) L = temp_Rpreoutput = permute( R + L, IP_INV) return preoutputdef DES_decrypt ( ciphertext64, key64) : """与加密过程完全对称,子密钥倒序""" permuted = permute( ciphertext64, IP) L, R = permuted[ : 32 ] , permuted[ 32 : ] for subkey in reversed ( generate_subkeys( key64) ) : temp_R = RR = xor( L, feistel( R, subkey) ) L = temp_Rreturn permute( R + L, IP_INV)
def text_to_bits ( text) : return [ int ( bit) for char in text for bit in f' { ord ( char) : 08b } ' ] def bits_to_text ( bits) : chars = [ chr ( int ( '' . join( map ( str , bits[ i: i+ 8 ] ) ) , 2 ) ) for i in range ( 0 , len ( bits) , 8 ) ] return '' . join( chars)
def triple_des_encrypt ( block64, key1, key2, key3= None ) : """3DES EDE 加密单个 64‑bit 块- key1, key2, key3: 各自为 64‑bit 位列表- 若未提供 key3,则自动回退为 2‑Key 3DES (K3 = K1)""" if key3 is None : key3 = key1 step1 = DES_encrypt( block64, key1) step2 = DES_decrypt( step1, key2) step3 = DES_encrypt( step2, key3) return step3def triple_des_decrypt ( block64, key1, key2, key3= None ) : """3DES EDE 解密单个 64‑bit 块顺序为 D_K3 ▸ E_K2 ▸ D_K1""" if key3 is None : key3 = key1 step1 = DES_decrypt( block64, key3) step2 = DES_encrypt( step1, key2) step3 = DES_decrypt( step2, key1) return step3if __name__ == "__main__" : plaintext = "ABCDEFGH" k1_ascii = "12345678" k2_ascii = "23456789" k3_ascii = "34567890" def str_to_bits ( s) : return [ int ( b) for ch in s for b in f" { ord ( ch) : 08b } " ] def bits_to_hex ( bits) : return hex ( int ( "" . join( map ( str , bits) ) , 2 ) ) [ 2 : ] . upper( ) . zfill( 16 ) def bits_to_str ( bits) : return "" . join( chr ( int ( "" . join( map ( str , bits[ i: i+ 8 ] ) ) , 2 ) ) for i in range ( 0 , len ( bits) , 8 ) ) pt_bits = str_to_bits( plaintext) k1_bits, k2_bits, k3_bits = map ( str_to_bits, ( k1_ascii, k2_ascii, k3_ascii) ) ct_bits = triple_des_encrypt( pt_bits, k1_bits, k2_bits, k3_bits) pt_back_bits = triple_des_decrypt( ct_bits, k1_bits, k2_bits, k3_bits) print ( "密文 (Hex) :" , bits_to_hex( ct_bits) ) print ( "解密后明文 :" , bits_to_str( pt_back_bits) )