日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

TEA加密算法的C/C++实现

發布時間:2025/3/20 c/c++ 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TEA加密算法的C/C++实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

TEA加密算法的C/C++實現

http://www.xxlinux.com/linux/article/development/soft/20070911/9687.html
時間:2007-09-11 11:02:34??來源:Linux聯盟收集整理??作者:
TEA(Tiny Encryption Algorithm)是一種簡單高效的加密算法,以加密解密速度快,實現簡單著稱。算法真的很簡單,TEA算法每一次可以操作64-bit(8-byte),采用128-bit(16-byte)作為key,算法采用迭代的形式,推薦的迭代輪數是64輪,最少32輪。目前我只知道QQ一直用的是16輪TEA。沒什么好說的,先給出C語言的源代碼(默認是32輪): 微型加密算法(TEA)及其相關變種(XTEA,Block?TEA,XXTEA)?都是分組加密算法,它們很容易被描述,實現也很簡單(典型的幾行代碼)。

TEA?算法最初是由劍橋計算機實驗室的?David?Wheeler?和?Roger?Needham?在?1994?年設計的。該算法使用?128?位的密鑰為?64?位的信息塊進行加密,它需要進行?64?輪迭代,盡管作者認為?32?輪已經足夠了。該算法使用了一個神秘常數δ作為倍數,它來源于黃金比率,以保證每一輪加密都不相同。但δ的精確值似乎并不重要,這里?TEA?把它定義為?δ=「(√5?-?1)231」(也就是程序中的?0×9E3779B9)。

之后?TEA?算法被發現存在缺陷,作為回應,設計者提出了一個?TEA?的升級版本——XTEA(有時也被稱為“tean”)。XTEA?跟?TEA?使用了相同的簡單運算,但它采用了截然不同的順序,為了阻止密鑰表攻擊,四個子密鑰(在加密過程中,原?128?位的密鑰被拆分為?4?個?32?位的子密鑰)采用了一種不太正規的方式進行混合,但速度更慢了。

在跟描述?XTEA?算法的同一份報告中,還介紹了另外一種被稱為?Block?TEA?算法的變種,它可以對?32?位大小任意倍數的變量塊進行操作。該算法將?XTEA?輪循函數依次應用于塊中的每個字,并且將它附加于它的鄰字。該操作重復多少輪依賴于塊的大小,但至少需要?6?輪。該方法的優勢在于它無需操作模式(CBC,OFB,CFB?等),密鑰可直接用于信息。對于長的信息它可能比?XTEA?更有效率。

在?1998?年,Markku-Juhani?Saarinen?給出了一個可有效攻擊?Block?TEA?算法的代碼,但之后很快?David?J.?Wheeler?和?Roger?M.?Needham?就給出了?Block?TEA?算法的修訂版,這個算法被稱為?XXTEA。XXTEA?使用跟?Block?TEA?相似的結構,但在處理塊中每個字時利用了相鄰字。它利用一個更復雜的?MX?函數代替了?XTEA?輪循函數,MX?使用?2?個輸入量。
?1?void?encrypt(unsigned?long?*v,?unsigned?long?*k)?{
?2?????unsigned?long?y=v[0],?z=v[1],?sum=0,?i;?????????/*?set?up?*/

?3?????unsigned?long?delta=0x9e3779b9;?????????????????/*?a?key?schedule?constant?*/
?4?????unsigned?long?a=k[0],?b=k[1],?c=k[2],?d=k[3];???/*?cache?key?*/
?5?????for?(i=0;?i?<?32;?i++)?{????????????????????????/*?basic?cycle?start?*/
?6?????????sum?+=?delta;
?7?????????y?+=?((z<<4)?+?a)?^?(z?+?sum)?^?((z>>5)?+
?b);
?8?????????z?+=?((y<<4)?+?c)?^?(y?+?sum)?^?((y>>5)?+?d);/*?end?cycle?*/

?9?????}
10?????v[0]=
y;
11?????v[1]=
z;
12?
}
13?

14?void?decrypt(unsigned?long?*v,?unsigned?long?*k)?{
15?????unsigned?long?y=v[0],?z=v[1],?sum=0xC6EF3720,?i;?/*?set?up?*/

16?????unsigned?long?delta=0x9e3779b9;??????????????????/*?a?key?schedule?constant?*/
17?????unsigned?long?a=k[0],?b=k[1],?c=k[2],?d=k[3];????/*?cache?key?*/
18?????for(i=0;?i<32;?i++)?{????????????????????????????/*?basic?cycle?start?*/
19?????????z?-=?((y<<4)?+?c)?^?(y?+?sum)?^?((y>>5)?+?d);
20?????????y?-=?((z<<4)?+?a)?^?(z?+?sum)?^?((z>>5)?+
?b);
21?????????sum?-=?delta;????????????????????????????????/*?end?cycle?*/

22?????}
23?????v[0]=
y;
24?????v[1]=
z;
25?}

C語言寫的用起來當然不方便,沒關系,用C++封裝以下就OK了:
util.h
?1?#ifndef?UTIL_H
?2?
#define?UTIL_H
?3?

?4?#include?<string>
?5?#include?<cmath>
?6?#include?<cstdlib>
?7?
?8?typedef?unsigned?char?byte;
?9?typedef?unsigned?long
?ulong;
10?

11?inline?double?logbase(double?base,?double?x)?{
12?????return?log(x)/
log(base);
13?
}
14?

15?/*
16?*convert?int?to?hex?char.
17?
*example:10?->?'A',15?->?'F'
18?*/

19?char?intToHexChar(int?x);
20?

21?/*
22?*convert?hex?char?to?int.
23?
*example:'A'?->?10,'F'?->?15
24?*/

25?int?hexCharToInt(char?hex);
26?

27?using?std::string;
28?/*

29?*convert?a?byte?array?to?hex?string.
30?
*hex?string?format?example:"AF?B0?80?7D"
31?*/

32?string?bytesToHexString(const?byte?*in,?size_t?size);
33?

34?/*
35?*convert?a?hex?string?to?a?byte?array.
36?
*hex?string?format?example:"AF?B0?80?7D"
37?*/

38?size_t?hexStringToBytes(const?string?&str,?byte?*out);
39?

40?#endif/*UTIL_H*/
util.cpp
?1?#include?"util.h"
?2?#include?<vector>
?3?
?4?using?namespace?std;
?5?

?6?char?intToHexChar(int?x)?{
?7?????static?const?char?HEX[16]?=
?{
?8?????????'0',?'1',?'2',?'3'
,
?9?????????'4',?'5',?'6',?'7'
,
10?????????'8',?'9',?'A',?'B'
,
11?????????'C',?'D',?'E',?'F'

12?????};
13?????return
?HEX[x];
14?
}
15?

16?int?hexCharToInt(char?hex)?{
17?????hex?=
?toupper(hex);
18?????if
?(isdigit(hex))
19?????????return?(hex?-?'0'
);
20?????if
?(isalpha(hex))
21?????????return?(hex?-?'A'?+?10
);
22?????return?0
;
23?
}
24?

25?string?bytesToHexString(const?byte?*in,?size_t?size)?{
26?
????string?str;
27?????for?(size_t?i?=?0;?i?<?size;?++
i)?{
28?????????int?t?=
?in[i];
29?????????int?a?=?t?/?16
;
30?????????int?b?=?t?%?16
;
31?????????str.append(1
,?intToHexChar(a));
32?????????str.append(1
,?intToHexChar(b));
33?????????if?(i?!=?size?-?1
)
34?????????????str.append(1,?'?'
);
35?
????}
36?????return
?str;
37?
}
38?

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

41?????vector<string>?vec;
42?????string::size_type?currPos?=?0,?prevPos?=?0
;
43?????while?((currPos?=?str.find('?',?prevPos))?!=
?string::npos)?{
44?????????string?b(str.substr(prevPos,?currPos?-
?prevPos));
45?
????????vec.push_back(b);
46?????????prevPos?=?currPos?+?1
;
47?
????}
48?????if?(prevPos?<
?str.size())?{
49?
????????string?b(str.substr(prevPos));
50?
????????vec.push_back(b);
51?
????}
52?????typedef?vector<string>
::size_type?sz_type;
53?????sz_type?size?=
?vec.size();
54?????for?(sz_type?i?=?0;?i?<?size;?++
i)?{
55?????????int?a?=?hexCharToInt(vec[i][0
]);
56?????????int?b?=?hexCharToInt(vec[i][1
]);
57?????????out[i]?=?a?*?16?+
?b;
58?
????}
59?????return
?size;
60?}

tea.h
?1?#ifndef?TEA_H
?2?
#define?TEA_H
?3?

?4?/*
?5?*for?htonl,htonl
?6?
*do?remember?link?"ws2_32.lib"
?7?*/

?8?#include?<winsock2.h>
?9?#include?"util.h"
10?
11?class?TEA?{
12?public
:
13?????TEA(const?byte?*key,?int?round?=?32,?bool?isNetByte?=?false
);
14?????TEA(const?TEA?&
rhs);
15?????TEA&?operator=(const?TEA?&
rhs);
16?????void?encrypt(const?byte?*in,?byte?*
out);
17?????void?decrypt(const?byte?*in,?byte?*
out);
18?private
:
19?????void?encrypt(const?ulong?*in,?ulong?*
out);
20?????void?decrypt(const?ulong?*in,?ulong?*
out);
21?????ulong?ntoh(ulong?netlong)?{?return?_isNetByte??
?ntohl(netlong)?:?netlong;?}
22?????ulong?hton(ulong?hostlong)?{?return?_isNetByte??
?htonl(hostlong)?:?hostlong;?}
23?private
:
24?????int?_round;?//iteration?round?to?encrypt?or?decrypt

25?????bool?_isNetByte;?//whether?input?bytes?come?from?network
26?????byte?_key[16];?//encrypt?or?decrypt?key
27?};
28?

29?#endif/*TEA_H*/
tea.cpp
?1?#include?"tea.h"
?2?#include?<cstring>?//for?memcpy,memset
?3?
?4?using?namespace?std;
?5?

?6?TEA::TEA(const?byte?*key,?int?round?/*=?32*/,?bool?isNetByte?/*=?false*/)
?7?
:_round(round)
?8?
,_isNetByte(isNetByte)?{
?9?????if?(key?!=?0
)
10?????????memcpy(_key,?key,?16
);
11?????else

12?????????memset(_key,?0,?16);
13?
}
14?

15?TEA::TEA(const?TEA?&rhs)
16?
:_round(rhs._round)
17?
,_isNetByte(rhs._isNetByte)?{
18?????memcpy(_key,?rhs._key,?16
);
19?
}
20?

21?TEA&?TEA::operator=(const?TEA?&rhs)?{
22?????if?(&rhs?!=?this
)?{
23?????????_round?=
?rhs._round;
24?????????_isNetByte?=
?rhs._isNetByte;
25?????????memcpy(_key,?rhs._key,?16
);
26?
????}
27?????return?*this
;
28?
}
29?

30?void?TEA::encrypt(const?byte?*in,?byte?*out)?{
31?????encrypt((const?ulong*)in,?(ulong*
)out);
32?
}
33?

34?void?TEA::decrypt(const?byte?*in,?byte?*out)?{
35?????decrypt((const?ulong*)in,?(ulong*
)out);
36?
}
37?

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

40?????ulong?*k?=?(ulong*)_key;
41?????register?ulong?y?=?ntoh(in[0
]);
42?????register?ulong?z?=?ntoh(in[1
]);
43?????register?ulong?a?=?ntoh(k[0
]);
44?????register?ulong?b?=?ntoh(k[1
]);
45?????register?ulong?c?=?ntoh(k[2
]);
46?????register?ulong?d?=?ntoh(k[3
]);
47?????register?ulong?delta?=?0x9E3779B9;?/*?(sqrt(5)-1)/2*2^32?*/

48?????register?int?round?=?_round;
49?????register?ulong?sum?=?0
;
50?

51?????while?(round--)?{????/*?basic?cycle?start?*/
52?????????sum?+=?delta;
53?????????y?+=?((z?<<?4)?+?a)?^?(z?+?sum)?^?((z?>>?5)?+
?b);
54?????????z?+=?((y?<<?4)?+?c)?^?(y?+?sum)?^?((y?>>?5)?+
?d);
55?????}????/*?end?cycle?*/

56?????out[0]?=?ntoh(y);
57?????out[1]?=
?ntoh(z);
58?
}
59?

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

62?????ulong?*k?=?(ulong*)_key;
63?????register?ulong?y?=?ntoh(in[0
]);
64?????register?ulong?z?=?ntoh(in[1
]);
65?????register?ulong?a?=?ntoh(k[0
]);
66?????register?ulong?b?=?ntoh(k[1
]);
67?????register?ulong?c?=?ntoh(k[2
]);
68?????register?ulong?d?=?ntoh(k[3
]);
69?????register?ulong?delta?=?0x9E3779B9;?/*?(sqrt(5)-1)/2*2^32?*/

70?????register?int?round?=?_round;
71?????register?ulong?sum?=?0
;
72?

73?????if?(round?==?32)
74?????????sum?=?0xC6EF3720;?/*?delta?<<?5*/

75?????else?if?(round?==?16)
76?????????sum?=?0xE3779B90;?/*?delta?<<?4*/

77?????else
78?????????sum?=?delta?<<?static_cast<int>(logbase(2,?round));
79?

80?????while?(round--)?{????/*?basic?cycle?start?*/
81?????????z?-=?((y?<<?4)?+?c)?^?(y?+?sum)?^?((y?>>?5)?+?d);
82?????????y?-=?((z?<<?4)?+?a)?^?(z?+?sum)?^?((z?>>?5)?+
?b);
83?????????sum?-=
?delta;
84?????}????/*?end?cycle?*/

85?????out[0]?=?ntoh(y);
86?????out[1]?=
?ntoh(z);
87?}

需要說明的是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
?1?#include?"tea.h"
?2?#include?"util.h"
?3?#include?<iostream>
?4?
?5?using?namespace?std;
?6?

?7?int?main()?{
?8?

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

14?????size_t?size_in?=?hexStringToBytes(plainStr,?plain);
15?????size_t?size_key?=
?hexStringToBytes(keyStr,?key);
16?

17?????if?(size_in?!=?SIZE_IN?||?size_key?!=?SIZE_KEY)
18?????????return?-1
;
19?

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

23?????TEA?tea(key,?16,?true);
24?
????tea.encrypt(plain,?crypt);
25?????cout?<<?"Crypt:?"?<<?bytesToHexString(crypt,?SIZE_OUT)?<<
?endl;
26?

27?????tea.decrypt(crypt,?plain);
28?????cout?<<?"Plain:?"?<<?bytesToHexString(plain,?SIZE_IN)?<<
?endl;
29?????return?0
;
30?}

運行結果:
Plain: AD DE E2 DB B3 E2 DB B3
Key? : 3A DA 75 21 DB E2 DB B3 11 B4 49 01 A5 C6 EA D4
Crypt: 3B 3B 4D 8C 24 3A FD F2
Plain: AD DE E2 DB B3 E2 DB B3

總結

以上是生活随笔為你收集整理的TEA加密算法的C/C++实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。