代码实现与示例
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
参数描述:
DELTA: 神秘常数δ,它来源于黄金比率,以保证每一轮加密都不相同。但δ的精确值似乎并不重要,这里 TEA 把它定义为 δ=「(√5 - 1)231」
v: 需要加解密的数据,格式为32位的无符号整数组成的数组
n: n表示需要加密的32位无符号整数的个数(例:n为1时,只有v数组中的第一个元素被加密了),n不能大于v的长度
k: 密钥,格式为4个32位无符号整数组成的数组,即密钥长度为128位
"""
import struct
from ctypes import c_uint32
DELTA = 0x9E3779B9
def encrypt(v, n, k):
rounds = 6 + int(52 / n)
sum = c_uint32(0)
z = v[n - 1].value
while rounds > 0:
sum.value += DELTA
e = (sum.value >> 2) & 3
p = 0
while p < n - 1:
y = v[p + 1].value
v[p].value += (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum.value ^ y) + (k[(p & 3) ^ e] ^ z)))
z = v[p].value
p += 1
y = v[0].value
v[n - 1].value += (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum.value ^ y) + (k[(p & 3) ^ e] ^ z)))
z = v[n - 1].value
rounds -= 1
def decrypt(v, n, k):
rounds = 6 + int(52 / n)
sum = c_uint32(rounds * DELTA)
y = v[0].value
while rounds > 0:
e = (sum.value >> 2) & 3
p = n - 1
while p > 0:
z = v[p - 1].value
v[p].value -= (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum.value ^ y) + (k[(p & 3) ^ e] ^ z)))
y = v[p].value
p -= 1
z = v[n - 1].value
v[0].value -= (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum.value ^ y) + (k[(p & 3) ^ e] ^ z)))
y = v[0].value
sum.value -= DELTA
rounds -= 1
def test1():
k = [2, 2, 3, 4]
v = [c_uint32(1), c_uint32(2)]
print('plain: 1 2')
encrypt(v, len(v), k)
print('encrypted: %X %X' % (v[0].value, v[1].value))
decrypt(v, len(v), k)
print('decrypted: %X %X' % (v[0].value, v[1].value))
def test2():
k = [0x01234567, 0x89ABCDEF, 0xFEDCBA98, 0x76543210]
v = []
# 示例的末尾补了两个空格,凑够4的倍数
plaintext = 'flag{dfccf8f0-0c97-11ec-82e0-0c9d9242e535} '
print('plain: %s' % plaintext)
# 将字符串转换成32位无符号整数的数组(注意大小端)
for i in range(0, len(plaintext), 4):
n = struct.unpack('>I', plaintext[i:i + 4])[0]
v.append(c_uint32(n))
# 加密
encrypt(v, len(v), k)
# 输出加密后的数据,以16进制字符串格式
str_list = []
for i in range(len(v)):
str_list.append(hex(v[i].value).replace('0x', '').replace('L', ''))
print('encrypted: %s' % ''.join(str_list))
# 解密
decrypt(v, len(v), k)
# 输出解密后的数据
str_list = []
for i in range(len(v)):
str_list.append(str(struct.pack('>I', v[i].value)))
print('decrypted: %s' % ''.join(str_list))
if __name__ == '__main__':
print('[test1]')
test1()
print('[test2]')
test2()
执行输出
[test1]
plain: 1 2
encrypted: C108A48B 7ABCCB32
decrypted: 1 2
[test2]
plain: flag{dfccf8f0-0c97-11ec-82e0-0c9d9242e535}
encrypted: 39cc3382f09c1c65b4949744f5f867a4235b1e9b4c2db199102978e8e1ed0f6aa4ebe327a8bf05a0305d16
decrypted: flag{dfccf8f0-0c97-11ec-82e0-0c9d9242e535}
参考