hex.node.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. import { assertU8, fromBuffer, fromUint8, E_STRING } from './fallback/_utils.js'
  2. import { E_HEX } from './fallback/hex.js'
  3. if (Buffer.TYPED_ARRAY_SUPPORT) throw new Error('Unexpected Buffer polyfill')
  4. const { toHex: webHex } = Uint8Array.prototype // Modern engines have this
  5. export function toHex(arr) {
  6. assertU8(arr)
  7. if (arr.length === 0) return ''
  8. if (webHex && arr.toHex === webHex) return arr.toHex()
  9. if (arr.constructor === Buffer && Buffer.isBuffer(arr)) return arr.hexSlice(0, arr.byteLength)
  10. return Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength).hexSlice(0, arr.byteLength)
  11. }
  12. // this is instant on 8-bit strings
  13. const NON_LATIN = /[^\x00-\xFF]/ // eslint-disable-line no-control-regex
  14. // Bugged Deno needs full validation, Node.js just needs a check that we don't truncate to 1-byte
  15. const denoBug = Buffer.from('ag', 'hex').length > 0
  16. const NON_HEX_CHECK = denoBug ? /[^\dA-Fa-f]/ : NON_LATIN
  17. // Unlike Buffer.from(), throws on invalid input
  18. export const fromHex = Uint8Array.fromHex
  19. ? (str, format = 'uint8') => fromUint8(Uint8Array.fromHex(str), format)
  20. : (str, format = 'uint8') => {
  21. if (typeof str !== 'string') throw new TypeError(E_STRING)
  22. if (str.length % 2 !== 0 || NON_HEX_CHECK.test(str)) throw new SyntaxError(E_HEX)
  23. // 64 bytes or less, in heap
  24. if (str.length <= 128) {
  25. const buf = Buffer.from(str, 'hex')
  26. if (buf.length * 2 !== str.length) throw new SyntaxError(E_HEX)
  27. return fromBuffer(buf, format)
  28. }
  29. const length = str.length / 2
  30. const buf = format === 'buffer' ? Buffer.allocUnsafe(length) : Buffer.allocUnsafeSlow(length) // avoid pooling
  31. const count = buf.hexWrite(str, 0, length)
  32. if (count !== length) throw new SyntaxError(E_HEX) // will stop on first non-hex character, so we can just validate length
  33. return fromBuffer(buf, format)
  34. }