crc.js 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import { assertU8 } from './fallback/_utils.js'
  2. import { crc32Table } from './fallback/crc.js'
  3. import { isHermes, isLE } from './fallback/platform.js'
  4. const T = crc32Table()
  5. const [T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ta, Tb, Tc, Td, Te, Tf] = Array.from(
  6. { length: 16 },
  7. (_, k) => T.subarray(k * 256, k * 256 + 256)
  8. )
  9. export function crc32(x) {
  10. assertU8(x)
  11. let c = -1
  12. let i = 0
  13. const n = x.length
  14. if (isLE && n > 1024) {
  15. const pre = (4 - (x.byteOffset & 3)) & 3
  16. for (; i < pre; i++) c = T0[(c ^ x[i]) & 0xff] ^ (c >>> 8)
  17. const words = (n - i) >>> 2
  18. const W = new (isHermes ? Uint32Array : Int32Array)(x.buffer, x.byteOffset + i, words)
  19. let j = 0
  20. for (const end = words - 3; j < end; j += 4) {
  21. const a = W[j] ^ c
  22. const b = W[j + 1]
  23. const d = W[j + 2]
  24. const e = W[j + 3]
  25. // prettier-ignore
  26. c =
  27. T[0xf_00 + (a & 0xff)] ^ T[0xe_00 + ((a >>> 8) & 0xff)] ^ T[0xd_00 + ((a >>> 16) & 0xff)] ^ T[0xc_00 + (a >>> 24)] ^
  28. T[0xb_00 + (b & 0xff)] ^ T[0xa_00 + ((b >>> 8) & 0xff)] ^ T[0x9_00 + ((b >>> 16) & 0xff)] ^ T[0x8_00 + (b >>> 24)] ^
  29. T[0x7_00 + (d & 0xff)] ^ T[0x6_00 + ((d >>> 8) & 0xff)] ^ T[0x5_00 + ((d >>> 16) & 0xff)] ^ T[0x4_00 + (d >>> 24)] ^
  30. T[0x3_00 + (e & 0xff)] ^ T[0x2_00 + ((e >>> 8) & 0xff)] ^ T[0x1_00 + ((e >>> 16) & 0xff)] ^ T[e >>> 24]
  31. }
  32. i += j * 4 // not << 2, so that inputs >= 2 GiB stay correct
  33. } else {
  34. for (const end = n - 15; i < end; i += 16) {
  35. // prettier-ignore
  36. c =
  37. Tf[(x[i] ^ c) & 0xff] ^ Te[(x[i + 1] ^ (c >>> 8)) & 0xff] ^
  38. Td[(x[i + 2] ^ (c >>> 16)) & 0xff] ^ Tc[x[i + 3] ^ (c >>> 24)] ^
  39. Tb[x[i + 4]] ^ Ta[x[i + 5]] ^ T9[x[i + 6]] ^ T8[x[i + 7]] ^
  40. T7[x[i + 8]] ^ T6[x[i + 9]] ^ T5[x[i + 10]] ^ T4[x[i + 11]] ^
  41. T3[x[i + 12]] ^ T2[x[i + 13]] ^ T1[x[i + 14]] ^ T0[x[i + 15]]
  42. }
  43. }
  44. for (let k = i; k < n; k++) c = T0[(c ^ x[k]) & 0xff] ^ (c >>> 8)
  45. return ~c >>> 0
  46. }