crc.node.js 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. import { crc32 as native } from 'node:zlib'
  2. import { assertU8 } from './fallback/_utils.js'
  3. import { crc32Table } from './fallback/crc.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. // zlib.crc32 is a V8 fast API call since Node.js 24.9.0 (nodejs/node#59813)
  10. const [major, minor] = (process.versions?.node || '0').split('.').map(Number)
  11. const fastNative = major > 24 || (major === 24 && minor >= 9)
  12. // Node.js x64 builds have SIMD crc32 disabled in zlib (nodejs/node#45268)
  13. // arm64 builds use the hardware crc32x instruction
  14. const NATIVE_MIN =
  15. !!globalThis.Deno || !!globalThis.Bun ? 0 : process.arch === 'arm64' ? (fastNative ? 0 : 64) : 256
  16. export function crc32(x) {
  17. assertU8(x)
  18. const n = x.length
  19. if (n >= NATIVE_MIN) return native(x)
  20. let c = -1
  21. let i = 0
  22. for (const end = n - 15; i < end; i += 16) {
  23. // prettier-ignore
  24. c =
  25. Tf[(x[i] ^ c) & 0xff] ^ Te[(x[i + 1] ^ (c >>> 8)) & 0xff] ^
  26. Td[(x[i + 2] ^ (c >>> 16)) & 0xff] ^ Tc[x[i + 3] ^ (c >>> 24)] ^
  27. Tb[x[i + 4]] ^ Ta[x[i + 5]] ^ T9[x[i + 6]] ^ T8[x[i + 7]] ^
  28. T7[x[i + 8]] ^ T6[x[i + 9]] ^ T5[x[i + 10]] ^ T4[x[i + 11]] ^
  29. T3[x[i + 12]] ^ T2[x[i + 13]] ^ T1[x[i + 14]] ^ T0[x[i + 15]]
  30. }
  31. for (let j = i; j < n; j++) c = T0[(c ^ x[j]) & 0xff] ^ (c >>> 8)
  32. return ~c >>> 0
  33. }