XXTEA.pm 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #/**********************************************************\
  2. #| |
  3. #| The implementation of PHPRPC Protocol 3.0 |
  4. #| |
  5. #| xxtea.pm |
  6. #| |
  7. #| Release 3.0.0 beta |
  8. #| Copyright (c) 2005-2007 by Team-PHPRPC |
  9. #| |
  10. #| WebSite: http://www.phprpc.org/ |
  11. #| http://www.phprpc.net/ |
  12. #| http://www.phprpc.com/ |
  13. #| http://sourceforge.net/projects/php-rpc/ |
  14. #| |
  15. #| Author: Ma Bingyao <[email protected]> |
  16. #| |
  17. #| This file may be distributed and/or modified under the |
  18. #| terms of the GNU Lesser General Public License (LGPL) |
  19. #| version 3.0 as published by the Free Software Foundation |
  20. #| and appearing in the included file LICENSE. |
  21. #| |
  22. #\**********************************************************/
  23. #
  24. # XXTEA encryption arithmetic module.
  25. #
  26. # Copyright (C) 2006-2007 Ma Bingyao <[email protected]>
  27. # Version: 1.00
  28. # LastModified: Nov 7, 2007
  29. # This library is free. You can redistribute it and/or modify it.
  30. #
  31. package Crypt::XXTEA;
  32. use bytes;
  33. use integer;
  34. use strict;
  35. use Exporter;
  36. use vars qw($VERSION @ISA @EXPORT);
  37. $VERSION = 1.00;
  38. @ISA = qw(Exporter);
  39. @EXPORT = qw(xxtea_encrypt xxtea_decrypt);
  40. *encrypt = \&xxtea_encrypt;
  41. *decrypt = \&xxtea_decrypt;
  42. sub _long2str {
  43. my ($v, $w) = @_;
  44. my $len = @{$v};
  45. my $n = ($len - 1) << 2;
  46. if ($w) {
  47. my $m = $v->[$len - 1];
  48. if (($m < $n - 3) || ($m > $n)) {
  49. return 0;
  50. }
  51. $n = $m;
  52. }
  53. my @s = ();
  54. for (my $i = 0; $i < $len; $i++) {
  55. $s[$i] = pack("V", $v->[$i]);
  56. }
  57. if ($w) {
  58. return substr(join('', @s), 0, $n);
  59. }
  60. else {
  61. return join('', @s);
  62. }
  63. }
  64. sub _str2long {
  65. my ($s, $w) = @_;
  66. my @v = unpack("V*", $s. "\0"x((4 - length($s) % 4) & 3));
  67. if ($w) {
  68. $v[@v] = length($s);
  69. }
  70. return @v;
  71. }
  72. sub xxtea_encrypt {
  73. my ($s, $k) = @_;
  74. if ($s eq "") {
  75. return "";
  76. }
  77. my @v = _str2long($s, 1);
  78. my @k = _str2long($k, 0);
  79. if (@k < 4) {
  80. for (my $i = @k; $i < 4; $i++) {
  81. $k[$i] = 0;
  82. }
  83. }
  84. my $n = $#v;
  85. my $z = $v[$n];
  86. my $y = $v[0];
  87. my $delta = 0x9E3779B9;
  88. my $q = 6 + 52 / ($n + 1);
  89. my $sum = 0;
  90. my $e;
  91. my $p;
  92. my $mx;
  93. while (0 < $q--) {
  94. $sum = ($sum + $delta) & 0xffffffff;
  95. $e = $sum >> 2 & 3;
  96. for ($p = 0; $p < $n; $p++) {
  97. $y = $v[$p + 1];
  98. $mx = ((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ (($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z)) & 0xffffffff;
  99. $z = $v[$p] = ($v[$p] + $mx) & 0xffffffff;
  100. }
  101. $y = $v[0];
  102. $mx = ((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ (($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z)) & 0xffffffff;
  103. $z = $v[$n] = ($v[$n] + $mx) & 0xffffffff;
  104. }
  105. return _long2str(\@v, 0);
  106. }
  107. sub xxtea_decrypt {
  108. my ($s, $k) = @_;
  109. if ($s eq "") {
  110. return "";
  111. }
  112. my @v = _str2long($s, 0);
  113. my @k = _str2long($k, 0);
  114. if (@k < 4) {
  115. for (my $i = @k; $i < 4; $i++) {
  116. $k[$i] = 0;
  117. }
  118. }
  119. my $n = $#v;
  120. my $z = $v[$n];
  121. my $y = $v[0];
  122. my $delta = 0x9E3779B9;
  123. my $q = 6 + 52 / ($n + 1);
  124. my $sum = ($q * $delta) & 0xffffffff;
  125. my $e;
  126. my $p;
  127. my $mx;
  128. while ($sum != 0) {
  129. $e = $sum >> 2 & 3;
  130. for ($p = $n; $p > 0; $p--) {
  131. $z = $v[$p - 1];
  132. $mx = ((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ (($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z)) & 0xffffffff;
  133. $y = $v[$p] = ($v[$p] - $mx) & 0xffffffff;
  134. }
  135. $z = $v[$n];
  136. $mx = ((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ (($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z)) & 0xffffffff;
  137. $y = $v[0] = ($v[0] - $mx) & 0xffffffff;
  138. $sum = ($sum - $delta) & 0xffffffff;
  139. }
  140. return _long2str(\@v, 1);
  141. }
  142. 1;
  143. __END__
  144. =head1 NAME
  145. Crypt::XXTEA - XXTEA encryption arithmetic module.
  146. =head1 SYNOPSIS
  147. use Crypt::XXTEA;
  148. =head1 DESCRIPTION
  149. XXTEA is a secure and fast encryption algorithm. It's suitable for web development. This module allows you to encrypt or decrypt a string using the algorithm.
  150. =head1 FUNCTIONS
  151. =over 4
  152. =item xxtea_encrypt
  153. my $ciphertext = xxtea_encrypt($plaintext, $key);
  154. This function encrypts $plaintext using $key and returns the $ciphertext.
  155. =item encrypt
  156. my $ciphertext = Crypt::XXTEA::encrypt($plaintext, $key);
  157. This function is the same as xxtea_encrypt.
  158. =item xxtea_decrypt
  159. my $plaintext = xxtea_decrypt($ciphertext, $key);
  160. This function decrypts $ciphertext using $key and returns the $plaintext.
  161. =item decrypt
  162. my $plaintext = Crypt::XXTEA::decrypt($ciphertext, $key);
  163. This function is the same as xxtea_decrypt.
  164. =back
  165. =head1 EXAMPLE
  166. use Crypt::XXTEA;
  167. my $ciphertext = xxtea_encrypt("Hello XXTEA.", "1234567890abcdef");
  168. my $plaintext = xxtea_decrypt($ciphertext, "1234567890abcdef");
  169. print $plaintext;
  170. $ciphertext = Crypt::XXTEA::encrypt("Hi XXTEA.", "1234567890abcdef");
  171. $plaintext = Crypt::XXTEA::decrypt($ciphertext, "1234567890abcdef");
  172. print $plaintext;
  173. =head1 NOTES
  174. If $plaintext is equal to "", it returns "".
  175. It returns 0 when fails to decrypt.
  176. Only the first 16 bytes of $key is used. if $key is shorter than 16 bytes, it will be padding \0.
  177. The XXTEA algorithm is stronger and faster than Crypt::DES, Crypt::Blowfish & Crypt::IDEA.
  178. =head1 SEE ALSO
  179. Crypt::DES
  180. Crypt::Blowfish
  181. Crypt::IDEA
  182. =head1 COPYRIGHT
  183. The implementation of the XXTEA algorithm was developed by,
  184. and is copyright of, Ma Bingyao ([email protected]).
  185. =cut