分享

tea javascript算法,支持utf8编码,解码方案。 ? 大虾的学习空间

 昵称3884271 2014-01-08

tea javascript算法,支持utf8编码,解码方案。


  1. /* – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – */
  2. /* Block TEA (xxtea) Tiny Encryption Algorithm implementation in JavaScript */
  3. /* (c) Chris Veness 2002-2009: www.movable-type.co.uk/tea-block.html */
  4. /* – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – */
  5. /* – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – */
  6. /* Algorithm: David Wheeler & Roger Needham, Cambridge University Computer Lab */
  7. /* http://www.cl./ftp/papers/djw-rmn/djw-rmn-tea.html (1994) */
  8. /* http://www.cl./ftp/users/djw3/xtea.ps (1997) */
  9. /* http://www.cl./ftp/users/djw3/xxtea.ps (1998) */
  10. /* – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – */
  11. var Tea = {}; // Tea namespace
  12. /*
  13. * encrypt text using Corrected Block TEA (xxtea) algorithm
  14. *
  15. <span id="more-119"></span>
  16. * @param {string} plaintext String to be encrypted (multi-byte safe)
  17. * @param {string} password Password to be used for encryption (1st 16 chars)
  18. * @returns {string} encrypted text
  19. */
  20. Tea.encrypt = function(plaintext, password) {
  21. if (plaintext.length == 0) return(”); // nothing to encrypt
  22. // convert string to array of longs after converting any multi-byte chars to UTF-8
  23. var v = Tea.strToLongs(Utf8.encode(plaintext));
  24. if (v.length <= 1) v[1] = 0; // algorithm doesn’t work for n<2 so fudge by adding a null
  25. // simply convert first 16 chars of password as key
  26. var k = Tea.strToLongs(Utf8.encode(password).slice(0,16));
  27. var n = v.length;
  28. // —- —-
  29. var z = v[n-1], y = v[0], delta = 0x9E3779B9;
  30. var mx, e, q = Math.floor(6 + 52/n), sum = 0;
  31. while (q– > 0) { // 6 + 52/n operations gives between 6 & 32 mixes on each word
  32. sum += delta;
  33. e = sum>>>2 & 3;
  34. for (var p = 0; p < n; p++) {
  35. y = v[(p+1)%n];
  36. mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
  37. z = v[p] += mx;
  38. }
  39. }
  40. // —- —-
  41. var ciphertext = Tea.longsToStr(v);
  42. return Base64.encode(ciphertext);
  43. }
  44. /*
  45. * decrypt text using Corrected Block TEA (xxtea) algorithm
  46. *
  47. * @param {string} ciphertext String to be decrypted
  48. * @param {string} password Password to be used for decryption (1st 16 chars)
  49. * @returns {string} decrypted text
  50. */
  51. Tea.decrypt = function(ciphertext, password) {
  52. if (ciphertext.length == 0) return(”);
  53. var v = Tea.strToLongs(Base64.decode(ciphertext));
  54. var k = Tea.strToLongs(Utf8.encode(password).slice(0,16));
  55. var n = v.length;
  56. // —- —-
  57. var z = v[n-1], y = v[0], delta = 0x9E3779B9;
  58. var mx, e, q = Math.floor(6 + 52/n), sum = q*delta;
  59. while (sum != 0) {
  60. e = sum>>>2 & 3;
  61. for (var p = n-1; p >= 0; p–) {
  62. z = v[p>0 ? p-1 : n-1];
  63. mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
  64. y = v[p] -= mx;
  65. }
  66. sum -= delta;
  67. }
  68. // —- —-
  69. var plaintext = Tea.longsToStr(v);
  70. // strip trailing null chars resulting from filling 4-char blocks:
  71. plaintext = plaintext.replace(/\0+$/,”);
  72. return Utf8.decode(plaintext);
  73. }
  74. /* – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – */
  75. // supporting functions
  76. Tea.strToLongs = function(s) { // convert string to array of longs, each containing 4 chars
  77. // note chars must be within ISO-8859-1 (with Unicode code-point < 256) to fit 4/long
  78. var l = new Array(Math.ceil(s.length/4));
  79. for (var i=0; i // note little-endian encoding – endianness is irrelevant as long as
  80. // it is the same in longsToStr()
  81. l[i] = s.charCodeAt(i*4) + (s.charCodeAt(i*4+1)<<8) +
  82. (s.charCodeAt(i*4+2)<<16) + (s.charCodeAt(i*4+3)<<24);
  83. }
  84. return l; // note running off the end of the string generates nulls since
  85. } // bitwise operators treat NaN as 0
  86. Tea.longsToStr = function(l) { // convert array of longs back to string
  87. var a = new Array(l.length);
  88. for (var i=0; i a[i] = String.fromCharCode(l[i] & 0xFF, l[i]>>>8 & 0xFF,
  89. l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF);
  90. }
  91. return a.join(”); // use Array.join() rather than repeated string appends for efficiency in IE
  92. }
  93. /* – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – */
  94. /* Base64 class: Base 64 encoding / decoding (c) Chris Veness 2002-2009 */
  95. /* note: depends on Utf8 class */
  96. /* – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – */
  97. var Base64 = {}; // Base64 namespace
  98. Base64.code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  99. /**
  100. * Encode string into Base64, as defined by RFC 4648 [http://tools./html/rfc4648]
  101. * (instance method extending String object). As per RFC 4648, no newlines are added.
  102. *
  103. * @param {String} str The string to be encoded as base-64
  104. * @param {Boolean} [utf8encode=false] Flag to indicate whether str is Unicode string to be encoded
  105. * to UTF8 before conversion to base64; otherwise string is assumed to be 8-bit characters
  106. * @returns {String} Base64-encoded string
  107. */
  108. Base64.encode = function(str, utf8encode) { // http://tools./html/rfc4648
  109. utf8encode = (typeof utf8encode == ‘undefined’) ? false : utf8encode;
  110. var o1, o2, o3, bits, h1, h2, h3, h4, e=[], pad = ”, c, plain, coded;
  111. var b64 = Base64.code;
  112. plain = utf8encode ? str.encodeUTF8() : str;
  113. c = plain.length % 3; // pad string to length of multiple of 3
  114. if (c > 0) { while (c++ < 3) { pad += ‘=’; plain += ‘\0′; } }
  115. // note: doing padding here saves us doing special-case packing for trailing 1 or 2 chars
  116. for (c=0; c o1 = plain.charCodeAt(c);
  117. o2 = plain.charCodeAt(c+1);
  118. o3 = plain.charCodeAt(c+2);
  119. bits = o1<<16 | o2<<8 | o3;
  120. h1 = bits>>18 & 0x3f;
  121. h2 = bits>>12 & 0x3f;
  122. h3 = bits>>6 & 0x3f;
  123. h4 = bits & 0x3f;
  124. // use hextets to index into code string
  125. e[c/3] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
  126. }
  127. coded = e.join(”); // join() is far faster than repeated string concatenation in IE
  128. // replace ‘A’s from padded nulls with ‘=’s
  129. coded = coded.slice(0, coded.length-pad.length) + pad;
  130. return coded;
  131. }
  132. /**
  133. * Decode string from Base64, as defined by RFC 4648 [http://tools./html/rfc4648]
  134. * (instance method extending String object). As per RFC 4648, newlines are not catered for.
  135. *
  136. * @param {String} str The string to be decoded from base-64
  137. * @param {Boolean} [utf8decode=false] Flag to indicate whether str is Unicode string to be decoded
  138. * from UTF8 after conversion from base64
  139. * @returns {String} decoded string
  140. */
  141. Base64.decode = function(str, utf8decode) {
  142. utf8decode = (typeof utf8decode == ‘undefined’) ? false : utf8decode;
  143. var o1, o2, o3, h1, h2, h3, h4, bits, d=[], plain, coded;
  144. var b64 = Base64.code;
  145. coded = utf8decode ? str.decodeUTF8() : str;
  146. for (var c=0; c h1 = b64.indexOf(coded.charAt(c));
  147. h2 = b64.indexOf(coded.charAt(c+1));
  148. h3 = b64.indexOf(coded.charAt(c+2));
  149. h4 = b64.indexOf(coded.charAt(c+3));
  150. bits = h1<<18 | h2<<12 | h3<<6 | h4;
  151. o1 = bits>>>16 & 0xff;
  152. o2 = bits>>>8 & 0xff;
  153. o3 = bits & 0xff;
  154. d[c/4] = String.fromCharCode(o1, o2, o3);
  155. // check for padding
  156. if (h4 == 0×40) d[c/4] = String.fromCharCode(o1, o2);
  157. if (h3 == 0×40) d[c/4] = String.fromCharCode(o1);
  158. }
  159. plain = d.join(”); // join() is far faster than repeated string concatenation in IE
  160. return utf8decode ? plain.decodeUTF8() : plain;
  161. }
  162. /* – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – */
  163. /* Utf8 class: encode / decode between multi-byte Unicode characters and UTF-8 multiple */
  164. /* single-byte character encoding (c) Chris Veness 2002-2009 */
  165. /* – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – */
  166. var Utf8 = {}; // Utf8 namespace
  167. /**
  168. * Encode multi-byte Unicode string into utf-8 multiple single-byte characters
  169. * (BMP / basic multilingual plane only)
  170. *
  171. * Chars in range U+0080 – U+07FF are encoded in 2 chars, U+0800 – U+FFFF in 3 chars
  172. *
  173. * @param {String} strUni Unicode string to be encoded as UTF-8
  174. * @returns {String} encoded string
  175. */
  176. Utf8.encode = function(strUni) {
  177. // use regular expressions & String.replace callback function for better efficiency
  178. // than procedural approaches
  179. var strUtf = strUni.replace(
  180. /[\u0080-\u07ff]/g, // U+0080 – U+07FF => 2 bytes 110yyyyy, 10zzzzzz
  181. function(c) {
  182. var cc = c.charCodeAt(0);
  183. return String.fromCharCode(0xc0 | cc>>6, 0×80 | cc&0x3f); }
  184. );
  185. strUtf = strUtf.replace(
  186. /[\u0800-\uffff]/g, // U+0800 – U+FFFF => 3 bytes 1110xxxx, 10yyyyyy, 10zzzzzz
  187. function(c) {
  188. var cc = c.charCodeAt(0);
  189. return String.fromCharCode(0xe0 | cc>>12, 0×80 | cc>>6&0x3F, 0×80 | cc&0x3f); }
  190. );
  191. return strUtf;
  192. }
  193. /**
  194. * Decode utf-8 encoded string back into multi-byte Unicode characters
  195. *
  196. * @param {String} strUtf UTF-8 string to be decoded back to Unicode
  197. * @returns {String} decoded string
  198. */
  199. Utf8.decode = function(strUtf) {
  200. var strUni = strUtf.replace(
  201. /[\u00c0-\u00df][\u0080-\u00bf]/g, // 2-byte chars
  202. function(c) { // (note parentheses for precence)
  203. var cc = (c.charCodeAt(0)&0x1f)<<6 | c.charCodeAt(1)&0x3f;
  204. return String.fromCharCode(cc); }
  205. );
  206. strUni = strUni.replace(
  207. /[\u00e0-\u00ef][\u0080-\u00bf][\u0080-\u00bf]/g, // 3-byte chars
  208. function(c) { // (note parentheses for precence)
  209. var cc = ((c.charCodeAt(0)&0x0f)<<12) | ((c.charCodeAt(1)&0x3f)<<6) | ( c.charCodeAt(2)&0x3f);
  210. return String.fromCharCode(cc); }
  211. );
  212. return strUni;
  213. }
  214. /* – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – */
  215. 普通的tea算法的
  216. // use (16 chars of) ‘password’ to encrypt ‘plaintext’
  217. function encrypt(plaintext, password) {
  218.   var v = new Array(2), k = new Array(4), s = "", i;
  219.   plaintext = escape(plaintext);  // use escape() so only have single-byte chars to encode
  220.   // build key directly from 1st 16 chars of password
  221.   for (var i=0; i<4; i++) k[i] = Str4ToLong(password.slice(i*4,(i+1)*4));
  222.   for (i=0; i
  223.     v[0] = Str4ToLong(plaintext.slice(i,i+4));  // … note this is ‘electronic codebook’ mode
  224.     v[1] = Str4ToLong(plaintext.slice(i+4,i+8));
  225.     code(v, k);
  226.     s += LongToStr4(v[0]) + LongToStr4(v[1]);
  227.   }
  228.   return escCtrlCh(s);
  229.   // note: if plaintext or password are passed as string objects, rather than strings, this
  230.   // function will throw an ‘Object doesn’t support this property or method’ error
  231. }
  232. // use (16 chars of) ‘password’ to decrypt ‘ciphertext’ with xTEA
  233. function decrypt(ciphertext, password) {
  234.   var v = new Array(2), k = new Array(4), s = "", i;
  235.   for (var i=0; i<4; i++) k[i] = Str4ToLong(password.slice(i*4,(i+1)*4));
  236.   ciphertext = unescCtrlCh(ciphertext);
  237.   for (i=0; i
  238.     v[0] = Str4ToLong(ciphertext.slice(i,i+4));
  239.     v[1] = Str4ToLong(ciphertext.slice(i+4,i+8));
  240.     decode(v, k);
  241.     s += LongToStr4(v[0]) + LongToStr4(v[1]);
  242.   }
  243.   // strip trailing null chars resulting from filling 4-char blocks:
  244.   s = s.replace(/\0+$/, ”);
  245.   return unescape(s);
  246. }
  247. function code(v, k) {
  248.   // Extended TEA: this is the 1997 revised version of Needham & Wheeler’s algorithm
  249.   // params: v[2] 64-bit value block; k[4] 128-bit key
  250.   var y = v[0], z = v[1];
  251.   var delta = 0x9E3779B9, limit = delta*32, sum = 0;
  252.   while (sum != limit) {
  253.     y += (z<<4 ^ z>>>5)+z ^ sum+k[sum & 3];
  254.     sum += delta;
  255.     z += (y<<4 ^ y>>>5)+y ^ sum+k[sum>>>11 & 3];
  256.     // note: unsigned right-shift ‘>>>’ is used in place of original ‘>>’, due to lack
  257.     // of ‘unsigned’ type declaration in JavaScript (thanks to Karsten Kraus for this)
  258.   }
  259.   v[0] = y; v[1] = z;
  260. }
  261. function decode(v, k) {
  262.   var y = v[0], z = v[1];
  263.   var delta = 0x9E3779B9, sum = delta*32;
  264.   while (sum != 0) {
  265.     z -= (y<<4 ^ y>>>5)+y ^ sum+k[sum>>>11 & 3];
  266.     sum -= delta;
  267.     y -= (z<<4 ^ z>>>5)+z ^ sum+k[sum & 3];
  268.   }
  269.   v[0] = y; v[1] = z;
  270. }
  271. // supporting functions
  272. function Str4ToLong(s) {  // convert 4 chars of s to a numeric long
  273.   var v = 0;
  274.   for (var i=0; i<4; i++) v |= s.charCodeAt(i) << i*8;   return isNaN(v) ? 0 : v; } function LongToStr4(v) {  // convert a numeric long to 4 char string   var s = String.fromCharCode(v & 0xFF, v>>8 & 0xFF, v>>16 & 0xFF, v>>24 & 0xFF);
  275.   return s;
  276. }
  277. function escCtrlCh(str) {  // escape control chars which might cause problems with encrypted texts
  278.   return str.replace(/[\0\t\n\v\f\r\xa0'"!]/g, function(c) { return ‘!’ + c.charCodeAt(0) + ‘!’; });
  279. }
  280. function unescCtrlCh(str) {  // unescape potentially problematic nulls and control characters
  281.   return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });
  282. }

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多