TEA加密算法的C/C++实现
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++实现的更多相关文章
- TEA加密算法的文件加密和解密的实现
一.TEA加密算法简介 TEA加密算法是由英国剑桥大学计算机实验室提出的一种对称分组加密算法.它采用扩散和混乱方法,对64位的明文数据块,用128位密钥分组进行加密,产生64位的密文数据块,其循环轮数 ...
- DES、AES、TEA加密算法的比较
1. DES算法介绍: DES算法具有对称性, 既可以用于加密又可以用于解密.对称性带来的一个很大的好处在于硬件实现, DES 的加密和解密可以用完全相同的硬件来实现.DES 算法的明文分组是 ...
- tea加密算法及其变种的研究
tea 介绍 "TEA" 的全称为"Tiny Encryption Algorithm" 是1994年由英国剑桥大学的David j.wheeler发明的. T ...
- TEA加密算法java版
这个算法简单,而且效率高,每次可以操作8个字节的数据,加密解密的KEY为16字节,即包含4个int数据的int型数组,加密轮数应为8的倍数,一般比较常用的轮数为64,32,16,推荐用64轮. 源代码 ...
- TEA算法
我们要讨论的最后一个分组密码加密算法是TEA(Tiny Encryption Algorithm).到目前为止,我们在前面所呈现的连线图可能会使你得出如下结论:分组密码加密算法必须是复杂的.TEA却能 ...
- 单片机上使用TEA加密通信(转)
源:单片机上使用TEA加密通信 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN7 开发环境:MDK4.72 单片机:STM32 说 ...
- 【搬运】Tea算法Java实现工具类
最近在做数据加密,目标是实现平台app的数据安全性,所以准备使用AES+Base64进行加密,适逢一个特长的json串AES加密不了,于是在谷歌了各种算法,判断是否合用,参见 各种加密算法比较 一文中 ...
- TEA加密/解密算法
在游戏项目中,一般需要对资源或数据进行加密保护,最简单高效的加密算法就是采用位与或之类的,但是比较容易被人分析出来.TEA加密算法不但比较简单,而且有很强的抗差分分析能力,加密速度也比较快.可以根据项 ...
- AliCTF 2016
上上周参加了阿里的CTF,靠着最后绝杀队伍有幸拿到了国内第一名,也顺利进入了XCTF Final.把自己做的几个题简单写了下,发出来也算个总结吧. PWN-FB 经典的null byte overfl ...
随机推荐
- 使用Discuz!自带参数防御CC攻击以及原理,修改Discuz X 开启防CC攻击后,不影响搜索引擎收录的方法
这部份的工作,以前花的时间太少. 希望能产生一定的作用. http://www.nigesb.com/discuz-cc-attacker-defence.html http://bbs.zb7.co ...
- C51变量的存储
一.全局变量和局部变量 全局变量和局部变量的区别在于作用域的不同.此外还有静态全局变量和静态局部变量. 全局变量作用域为全局,在一个源文件中定义,其他的源文件也可以应用.在其他的源文件中使用exter ...
- ORA-3136报错
当使用错误的用户名或密码登陆数据库时,会提示如下报错内容: bash-4.1$ sqlplus a/a@test SQL*Plus: Release 10.2.0.4.0 - Production o ...
- [置顶] Objective-C ,ios,iphone开发基础:在UITextField输入完以后,隐藏键盘,
在x-code Version 4.3.2 (4E2002)下编译: 在 Controller. m 文件下添加如下实例方法即可: - (void)viewDidUnload { [super vie ...
- 提高xshell使用效率
1.快速命令集. 2.鼠标复制粘贴设置. 3.配色方案. 4.esc切换到英文输入. 设置入口:
- 详细解读Jquery各Ajax函数:$.get(),$.post(),$.ajax(),$.getJSON() —(转)
一,$.get(url,[data],[callback]) 说明:url为请求地址,data为请求数据的列表(是可选的,也可以将要传的参数写在url里面),callback为请求成功后的回调函数,该 ...
- python实现二叉树和它的七种遍历
介绍: 树是数据结构中很重要的一种,基本的用途是用来提高查找效率,对于要反复查找的情况效果更佳,如二叉排序树.FP-树. 另外能够用来提高编码效率,如哈弗曼树. 代码: 用python实现树的构造和几 ...
- Servlet实现Session
(1)首先看一下项目的结构 是在tomcat--webaps下的myWebSites项目 在myWebSites下有仅仅有WEB-INF目录 在WEB-INF目录中有 一下目录(在classes目录 ...
- 自增运算a++和++b(1)
#include<reg52.h> #define uint unsigned int #define uchar unsigned char uchar code f[]={0x3f,0 ...
- [HeadFirst-HTMLCSS学习笔记][第十二章HTML5标记]
考虑HTML结构 HTML5即是把原来<div>换成一些更特定的元素.能够更明确指示包含什么内容. (页眉,导航,页脚,文章) article nav 导航 header footer t ...