TEA(Tiny Encryption Algorithm) 是一种简单高效的加密算法,以加密解密速度快,实现简单著称。算法真的很简单,TEA算法每一次可以操作64-bit(8-byte),采用128-bit(16-byte)作为key,算法采用迭代的形式,推荐的迭代轮数是64轮,最少32轮。目前我只知道QQ一直用的是16轮TEA。没什么好说的,先给出C语言的源代码(默认是32轮):

void encrypt(unsigned long *v, unsigned long *k) {
    unsigned ], z=v[], sum=, i;         /* set up */
    unsigned long delta=0x9e3779b9;                 /* a key schedule constant */
    unsigned ], b=k[], c=k[], d=k[];   /* cache key */
    ; i < ; i++) {                        /* basic cycle start */
        sum += delta;
        y += ((z<<) + a) ^ (z + sum) ^ ((z>>) + b);
        z += ((y<<) + c) ^ (y + sum) ^ ((y>>) + d);/* end cycle */
    }
    v[]=y;
    v[]=z;
}

void decrypt(unsigned long *v, unsigned long *k) {
    unsigned ], z=v[], sum=0xC6EF3720, i; /* set up */
    unsigned long delta=0x9e3779b9;                  /* a key schedule constant */
    unsigned ], b=k[], c=k[], d=k[];    /* cache key */
    ; i<; i++) {                            /* basic cycle start */
        z -= ((y<<) + c) ^ (y + sum) ^ ((y>>) + d);
        y -= ((z<<) + a) ^ (z + sum) ^ ((z>>) + b);
        sum -= delta;                                /* end cycle */
    }
    v[]=y;
    v[]=z;
}

C语言写的用起来当然不方便,没关系,用C++封装以下就OK了:

util.h

#ifndef UTIL_H
#define UTIL_H

#include <string>
#include <cstdlib>

typedef unsigned char byte;
typedef unsigned long ulong;

/*
*convert int to hex char.
*example:10 -> 'A',15 -> 'F'
*/
char intToHexChar(int x);

/*
*convert hex char to int.
*example:'A' -> 10,'F' -> 15
*/
int hexCharToInt(char hex);

using std::string;
/*
*convert a byte array to hex string.
*hex string format example:"AF B0 80 7D"
*/
string bytesToHexString(const byte *in, size_t size);

/*
*convert a hex string to a byte array.
*hex string format example:"AF B0 80 7D"
*/
size_t hexStringToBytes(const string &str, byte *out);

#endif/*UTIL_H*/

util.cpp

#include "util.h"
#include <vector>

using namespace std;

char intToHexChar(int x) {
    ] = {
        ',
        ',
        ', 'A', 'B',
        'C', 'D', 'E', 'F'
    };
    return HEX[x];
}

int hexCharToInt(char hex) {
    hex = toupper(hex);
    if (isdigit(hex))
        ');
    if (isalpha(hex))
        );
    ;
}

string bytesToHexString(const byte *in, size_t size) {
    string str;
    ; i < size; ++i) {
        int t = in[i];
        ;
        ;
        str.append(, intToHexChar(a));
        str.append(, intToHexChar(b));
        )
            str.append(, ' ');
    }
    return str;
}

size_t hexStringToBytes(const string &str, byte *out) {

    vector<string> vec;
    , prevPos = ;
    while ((currPos = str.find(' ', prevPos)) != string::npos) {
        string b(str.substr(prevPos, currPos - prevPos));
        vec.push_back(b);
        prevPos = currPos + ;
    }
    if (prevPos < str.size()) {
        string b(str.substr(prevPos));
        vec.push_back(b);
    }
    typedef vector<string>::size_type sz_type;
    sz_type size = vec.size();
    ; i < size; ++i) {
        ]);
        ]);
         + b;
    }
    return size;
}

tea.h

#ifndef TEA_H
#define TEA_H

/*
*for htonl,htonl
*do remember link "ws2_32.lib"
*/
#include <winsock2.h>
#include "util.h"

class TEA {
public:
    TEA(, bool isNetByte = false);
    TEA(const TEA &rhs);
    TEA& operator=(const TEA &rhs);
    void encrypt(const byte *in, byte *out);
    void decrypt(const byte *in, byte *out);
private:
    void encrypt(const ulong *in, ulong *out);
    void decrypt(const ulong *in, ulong *out);
    ulong ntoh(ulong netlong) { return _isNetByte ? ntohl(netlong) : netlong; }
    ulong hton(ulong hostlong) { return _isNetByte ? htonl(hostlong) : hostlong; }
private:
    int _round; //iteration round to encrypt or decrypt
    bool _isNetByte; //whether input bytes come from network
    ]; //encrypt or decrypt key
};

#endif/*TEA_H*/

tea.cpp

#include "tea.h"
#include <cstring> //for memcpy,memset

using namespace std;

TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)
:_round(round)
,_isNetByte(isNetByte) {
    )
        memcpy(_key, key, );
    else
        memset(_key, , );
}

TEA::TEA(const TEA &rhs)
:_round(rhs._round)
,_isNetByte(rhs._isNetByte) {
    memcpy(_key, rhs._key, );
}

TEA& TEA::operator=(const TEA &rhs) {
    if (&rhs != this) {
        _round = rhs._round;
        _isNetByte = rhs._isNetByte;
        memcpy(_key, rhs._key, );
    }
    return *this;
}

void TEA::encrypt(const byte *in, byte *out) {
    encrypt((const ulong*)in, (ulong*)out);
}

void TEA::decrypt(const byte *in, byte *out) {
    decrypt((const ulong*)in, (ulong*)out);
}

void TEA::encrypt(const ulong *in, ulong *out) {

    ulong *k = (ulong*)_key;
    register ]);
    register ]);
    register ]);
    register ]);
    register ]);
    register ]);
    register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
    register int round = _round;
    register ;

    while (round--) {    /* basic cycle start */
        sum += delta;
        y += ((z << ) + a) ^ (z + sum) ^ ((z >> ) + b);
        z += ((y << ) + c) ^ (y + sum) ^ ((y >> ) + d);
    }    /* end cycle */
    ] = ntoh(y);
    ] = ntoh(z);
}

void TEA::decrypt(const ulong *in, ulong *out) {

    ulong *k = (ulong*)_key;
    register ]);
    register ]);
    register ]);
    register ]);
    register ]);
    register ]);
    register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */
    register int round = _round;
    register ;

    )
        sum = 0xC6EF3720; /* delta << 5*/
    )
        sum = 0xE3779B90; /* delta << 4*/
    else
        sum = delta * round;

    while (round--) {    /* basic cycle start */
        z -= ((y << ) + c) ^ (y + sum) ^ ((y >> ) + d);
        y -= ((z << ) + a) ^ (z + sum) ^ ((z >> ) + b);
        sum -= delta;
    }    /* end cycle */
    ] = ntoh(y);
    ] = ntoh(z);
}

需要说明的是TEA的构造函数:
TEA(const byte *key, int round = 32, bool isNetByte = false);
1.key - 加密或解密用的128-bit(16byte)密钥。
2.round - 加密或解密的轮数,常用的有64,32,16。
3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!

最后当然少不了测试代码:
test.cpp

#include "tea.h"
#include "util.h"
#include <iostream>

using namespace std;

int main() {

    const string plainStr("AD DE E2 DB B3 E2 DB B3");
    const string keyStr("3A DA 75 21 DB E2 DB B3 11 B4 49 01 A5 C6 EA D4");
    , SIZE_OUT = , SIZE_KEY = ;
    byte plain[SIZE_IN], crypt[SIZE_OUT], key[SIZE_KEY];

    size_t size_in = hexStringToBytes(plainStr, plain);
    size_t size_key = hexStringToBytes(keyStr, key);

    if (size_in != SIZE_IN || size_key != SIZE_KEY)
        ;

    cout << "Plain: " << bytesToHexString(plain, size_in) << endl;
    cout << "Key  : " << bytesToHexString(key, size_key) << endl;

    TEA tea(key, , true);
    tea.encrypt(plain, crypt);
    cout << "Crypt: " << bytesToHexString(crypt, SIZE_OUT) << endl;

    tea.decrypt(crypt, plain);
    cout << "Plain: " << bytesToHexString(plain, SIZE_IN) << endl;
    ;
}

运行结果:

Plain: AD DE E2 DB B3 E2 DB B3
Key  : 3A DA   DB E2 DB B3  B4   A5 C6 EA D4
Crypt: 3B 3B 4D 8C  3A FD F2
Plain: AD DE E2 DB B3 E2 DB B3

TEA加密算法的C/C++实现的更多相关文章

  1. TEA加密算法的文件加密和解密的实现

    一.TEA加密算法简介 TEA加密算法是由英国剑桥大学计算机实验室提出的一种对称分组加密算法.它采用扩散和混乱方法,对64位的明文数据块,用128位密钥分组进行加密,产生64位的密文数据块,其循环轮数 ...

  2. DES、AES、TEA加密算法的比较

    1.     DES算法介绍: DES算法具有对称性, 既可以用于加密又可以用于解密.对称性带来的一个很大的好处在于硬件实现, DES 的加密和解密可以用完全相同的硬件来实现.DES 算法的明文分组是 ...

  3. tea加密算法及其变种的研究

    tea 介绍 "TEA" 的全称为"Tiny Encryption Algorithm" 是1994年由英国剑桥大学的David j.wheeler发明的. T ...

  4. TEA加密算法java版

    这个算法简单,而且效率高,每次可以操作8个字节的数据,加密解密的KEY为16字节,即包含4个int数据的int型数组,加密轮数应为8的倍数,一般比较常用的轮数为64,32,16,推荐用64轮. 源代码 ...

  5. TEA算法

    我们要讨论的最后一个分组密码加密算法是TEA(Tiny Encryption Algorithm).到目前为止,我们在前面所呈现的连线图可能会使你得出如下结论:分组密码加密算法必须是复杂的.TEA却能 ...

  6. 单片机上使用TEA加密通信(转)

    源:单片机上使用TEA加密通信 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN7 开发环境:MDK4.72 单片机:STM32 说 ...

  7. 【搬运】Tea算法Java实现工具类

    最近在做数据加密,目标是实现平台app的数据安全性,所以准备使用AES+Base64进行加密,适逢一个特长的json串AES加密不了,于是在谷歌了各种算法,判断是否合用,参见 各种加密算法比较 一文中 ...

  8. TEA加密/解密算法

    在游戏项目中,一般需要对资源或数据进行加密保护,最简单高效的加密算法就是采用位与或之类的,但是比较容易被人分析出来.TEA加密算法不但比较简单,而且有很强的抗差分分析能力,加密速度也比较快.可以根据项 ...

  9. AliCTF 2016

    上上周参加了阿里的CTF,靠着最后绝杀队伍有幸拿到了国内第一名,也顺利进入了XCTF Final.把自己做的几个题简单写了下,发出来也算个总结吧. PWN-FB 经典的null byte overfl ...

随机推荐

  1. RMAN备份FORMAT格式中%的含义

    使用格式串先看例子:Configure channel 1 device type disk format 'd:/backup/orcl/backup_%U';在configure 命令中经常使用格 ...

  2. android run process

    http://www.jb51.net/article/32798.htm http://www.elecfans.com/tongxin/119/20120315263977.html 图 1 详细 ...

  3. HDU 3507 PrintArticle (单调队列优化)

    题意:给出一个数列C,一个数字M,将数列分成若干段,每段的代价为(设这段的数字为k个): dp[i]=min(dp[j]+(sum[i]-sum[j])*(sum[i]-sum[j])+M) 若j1& ...

  4. LeetCode_Surrounded Regions

    Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. A region is captured ...

  5. The end of other

    The end of other For language training our Robots want to learn about suffixes. In this task, you ar ...

  6. 转:完善eclipse+pdt作php开发中的代码提示能力

    在eclipse开发中 ,可能由于各种原因导致项目文件(eclipse内置)丢失或错乱, 因而, 失去一些能力.. 以下是经过被痛苦折磨后查阅总结的一点东西 设置完下面内容, 支持以下特性 PHP: ...

  7. 导入旧数据需要 使用date插件

    "@version" => "1", "@timestamp" => "2016-09-12T08:31:06.630 ...

  8. Uva272.TEX Quotes

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  9. Python Open Flash Chart (pyOFC2) — Home

    Python Open Flash Chart (pyOFC2) - Home pyOFC2 Python Open Flash Chart 2

  10. csdn博客被一个无名网站套用,不知大家是否也是这样?

    今天闲来无事,用google搜索了一下自己csdn的博客名,查看了一下搜索结果,发现自己在csdn上的博客被其他一下网站转载了,转载后注明作者的网站这里我也就不去说了,问题是我发现了一个名叫“开心问答 ...