utils.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. 'use strict';
  2. var assert = require('minimalistic-assert');
  3. var inherits = require('inherits');
  4. exports.inherits = inherits;
  5. function isSurrogatePair(msg, i) {
  6. if ((msg.charCodeAt(i) & 0xFC00) !== 0xD800) {
  7. return false;
  8. }
  9. if (i < 0 || i + 1 >= msg.length) {
  10. return false;
  11. }
  12. return (msg.charCodeAt(i + 1) & 0xFC00) === 0xDC00;
  13. }
  14. function toArray(msg, enc) {
  15. if (Array.isArray(msg))
  16. return msg.slice();
  17. if (!msg)
  18. return [];
  19. var res = [];
  20. if (typeof msg === 'string') {
  21. if (!enc) {
  22. // Inspired by stringToUtf8ByteArray() in closure-library by Google
  23. // https://github.com/google/closure-library/blob/8598d87242af59aac233270742c8984e2b2bdbe0/closure/goog/crypt/crypt.js#L117-L143
  24. // Apache License 2.0
  25. // https://github.com/google/closure-library/blob/master/LICENSE
  26. var p = 0;
  27. for (var i = 0; i < msg.length; i++) {
  28. var c = msg.charCodeAt(i);
  29. if (c < 128) {
  30. res[p++] = c;
  31. } else if (c < 2048) {
  32. res[p++] = (c >> 6) | 192;
  33. res[p++] = (c & 63) | 128;
  34. } else if (isSurrogatePair(msg, i)) {
  35. c = 0x10000 + ((c & 0x03FF) << 10) + (msg.charCodeAt(++i) & 0x03FF);
  36. res[p++] = (c >> 18) | 240;
  37. res[p++] = ((c >> 12) & 63) | 128;
  38. res[p++] = ((c >> 6) & 63) | 128;
  39. res[p++] = (c & 63) | 128;
  40. } else {
  41. res[p++] = (c >> 12) | 224;
  42. res[p++] = ((c >> 6) & 63) | 128;
  43. res[p++] = (c & 63) | 128;
  44. }
  45. }
  46. } else if (enc === 'hex') {
  47. msg = msg.replace(/[^a-z0-9]+/ig, '');
  48. if (msg.length % 2 !== 0)
  49. msg = '0' + msg;
  50. for (i = 0; i < msg.length; i += 2)
  51. res.push(parseInt(msg[i] + msg[i + 1], 16));
  52. }
  53. } else {
  54. for (i = 0; i < msg.length; i++)
  55. res[i] = msg[i] | 0;
  56. }
  57. return res;
  58. }
  59. exports.toArray = toArray;
  60. function toHex(msg) {
  61. var res = '';
  62. for (var i = 0; i < msg.length; i++)
  63. res += zero2(msg[i].toString(16));
  64. return res;
  65. }
  66. exports.toHex = toHex;
  67. function htonl(w) {
  68. var res = (w >>> 24) |
  69. ((w >>> 8) & 0xff00) |
  70. ((w << 8) & 0xff0000) |
  71. ((w & 0xff) << 24);
  72. return res >>> 0;
  73. }
  74. exports.htonl = htonl;
  75. function toHex32(msg, endian) {
  76. var res = '';
  77. for (var i = 0; i < msg.length; i++) {
  78. var w = msg[i];
  79. if (endian === 'little')
  80. w = htonl(w);
  81. res += zero8(w.toString(16));
  82. }
  83. return res;
  84. }
  85. exports.toHex32 = toHex32;
  86. function zero2(word) {
  87. if (word.length === 1)
  88. return '0' + word;
  89. else
  90. return word;
  91. }
  92. exports.zero2 = zero2;
  93. function zero8(word) {
  94. if (word.length === 7)
  95. return '0' + word;
  96. else if (word.length === 6)
  97. return '00' + word;
  98. else if (word.length === 5)
  99. return '000' + word;
  100. else if (word.length === 4)
  101. return '0000' + word;
  102. else if (word.length === 3)
  103. return '00000' + word;
  104. else if (word.length === 2)
  105. return '000000' + word;
  106. else if (word.length === 1)
  107. return '0000000' + word;
  108. else
  109. return word;
  110. }
  111. exports.zero8 = zero8;
  112. function join32(msg, start, end, endian) {
  113. var len = end - start;
  114. assert(len % 4 === 0);
  115. var res = new Array(len / 4);
  116. for (var i = 0, k = start; i < res.length; i++, k += 4) {
  117. var w;
  118. if (endian === 'big')
  119. w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];
  120. else
  121. w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];
  122. res[i] = w >>> 0;
  123. }
  124. return res;
  125. }
  126. exports.join32 = join32;
  127. function split32(msg, endian) {
  128. var res = new Array(msg.length * 4);
  129. for (var i = 0, k = 0; i < msg.length; i++, k += 4) {
  130. var m = msg[i];
  131. if (endian === 'big') {
  132. res[k] = m >>> 24;
  133. res[k + 1] = (m >>> 16) & 0xff;
  134. res[k + 2] = (m >>> 8) & 0xff;
  135. res[k + 3] = m & 0xff;
  136. } else {
  137. res[k + 3] = m >>> 24;
  138. res[k + 2] = (m >>> 16) & 0xff;
  139. res[k + 1] = (m >>> 8) & 0xff;
  140. res[k] = m & 0xff;
  141. }
  142. }
  143. return res;
  144. }
  145. exports.split32 = split32;
  146. function rotr32(w, b) {
  147. return (w >>> b) | (w << (32 - b));
  148. }
  149. exports.rotr32 = rotr32;
  150. function rotl32(w, b) {
  151. return (w << b) | (w >>> (32 - b));
  152. }
  153. exports.rotl32 = rotl32;
  154. function sum32(a, b) {
  155. return (a + b) >>> 0;
  156. }
  157. exports.sum32 = sum32;
  158. function sum32_3(a, b, c) {
  159. return (a + b + c) >>> 0;
  160. }
  161. exports.sum32_3 = sum32_3;
  162. function sum32_4(a, b, c, d) {
  163. return (a + b + c + d) >>> 0;
  164. }
  165. exports.sum32_4 = sum32_4;
  166. function sum32_5(a, b, c, d, e) {
  167. return (a + b + c + d + e) >>> 0;
  168. }
  169. exports.sum32_5 = sum32_5;
  170. function sum64(buf, pos, ah, al) {
  171. var bh = buf[pos];
  172. var bl = buf[pos + 1];
  173. var lo = (al + bl) >>> 0;
  174. var hi = (lo < al ? 1 : 0) + ah + bh;
  175. buf[pos] = hi >>> 0;
  176. buf[pos + 1] = lo;
  177. }
  178. exports.sum64 = sum64;
  179. function sum64_hi(ah, al, bh, bl) {
  180. var lo = (al + bl) >>> 0;
  181. var hi = (lo < al ? 1 : 0) + ah + bh;
  182. return hi >>> 0;
  183. }
  184. exports.sum64_hi = sum64_hi;
  185. function sum64_lo(ah, al, bh, bl) {
  186. var lo = al + bl;
  187. return lo >>> 0;
  188. }
  189. exports.sum64_lo = sum64_lo;
  190. function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {
  191. var carry = 0;
  192. var lo = al;
  193. lo = (lo + bl) >>> 0;
  194. carry += lo < al ? 1 : 0;
  195. lo = (lo + cl) >>> 0;
  196. carry += lo < cl ? 1 : 0;
  197. lo = (lo + dl) >>> 0;
  198. carry += lo < dl ? 1 : 0;
  199. var hi = ah + bh + ch + dh + carry;
  200. return hi >>> 0;
  201. }
  202. exports.sum64_4_hi = sum64_4_hi;
  203. function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {
  204. var lo = al + bl + cl + dl;
  205. return lo >>> 0;
  206. }
  207. exports.sum64_4_lo = sum64_4_lo;
  208. function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
  209. var carry = 0;
  210. var lo = al;
  211. lo = (lo + bl) >>> 0;
  212. carry += lo < al ? 1 : 0;
  213. lo = (lo + cl) >>> 0;
  214. carry += lo < cl ? 1 : 0;
  215. lo = (lo + dl) >>> 0;
  216. carry += lo < dl ? 1 : 0;
  217. lo = (lo + el) >>> 0;
  218. carry += lo < el ? 1 : 0;
  219. var hi = ah + bh + ch + dh + eh + carry;
  220. return hi >>> 0;
  221. }
  222. exports.sum64_5_hi = sum64_5_hi;
  223. function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
  224. var lo = al + bl + cl + dl + el;
  225. return lo >>> 0;
  226. }
  227. exports.sum64_5_lo = sum64_5_lo;
  228. function rotr64_hi(ah, al, num) {
  229. var r = (al << (32 - num)) | (ah >>> num);
  230. return r >>> 0;
  231. }
  232. exports.rotr64_hi = rotr64_hi;
  233. function rotr64_lo(ah, al, num) {
  234. var r = (ah << (32 - num)) | (al >>> num);
  235. return r >>> 0;
  236. }
  237. exports.rotr64_lo = rotr64_lo;
  238. function shr64_hi(ah, al, num) {
  239. return ah >>> num;
  240. }
  241. exports.shr64_hi = shr64_hi;
  242. function shr64_lo(ah, al, num) {
  243. var r = (ah << (32 - num)) | (al >>> num);
  244. return r >>> 0;
  245. }
  246. exports.shr64_lo = shr64_lo;