代码实现与示例

#!/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}  

参考

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐