bytesUtils.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. export enum Endian {
  2. BE = 'be',
  3. LE = 'le',
  4. }
  5. const UTF8_ENCODER = new TextEncoder();
  6. const UTF8_DECODER = new TextDecoder();
  7. function swapWord32Bytes(bytes: Uint8Array): Uint8Array {
  8. const out = new Uint8Array(bytes.length);
  9. let i = 0;
  10. for (; i + 4 <= bytes.length; i += 4) {
  11. out[i] = bytes[i + 3]!;
  12. out[i + 1] = bytes[i + 2]!;
  13. out[i + 2] = bytes[i + 1]!;
  14. out[i + 3] = bytes[i]!;
  15. }
  16. for (; i < bytes.length; i++) out[i] = bytes[i]!;
  17. return out;
  18. }
  19. /** 将小端数据转换为大端数据 */
  20. export function littleEndianToBigEndian(bytes: Uint8Array): Uint8Array {
  21. return swapWord32Bytes(bytes);
  22. }
  23. /** 将大端数据转换为小端数据 */
  24. export function bigEndianToLittleEndian(bytes: Uint8Array): Uint8Array {
  25. return swapWord32Bytes(bytes);
  26. }
  27. /** 将数字转为 4 字节二进制;endian 为 'be' 大端 或 'le' 小端 */
  28. export function numberToBytes(value: number, endian: Endian = Endian.BE): Uint8Array {
  29. const buf = new Uint8Array(4);
  30. numberToBytesAt(value, buf, 0, endian);
  31. return buf;
  32. }
  33. /** 在 buffer 的 offset 处写入 4 字节无符号整数 */
  34. export function numberToBytesAt(
  35. value: number,
  36. buffer: Uint8Array,
  37. offset: number,
  38. endian: Endian = Endian.BE
  39. ): void {
  40. if (endian === Endian.BE) {
  41. buffer[offset] = (value >>> 24) & 0xff;
  42. buffer[offset + 1] = (value >>> 16) & 0xff;
  43. buffer[offset + 2] = (value >>> 8) & 0xff;
  44. buffer[offset + 3] = value & 0xff;
  45. } else {
  46. buffer[offset] = value & 0xff;
  47. buffer[offset + 1] = (value >>> 8) & 0xff;
  48. buffer[offset + 2] = (value >>> 16) & 0xff;
  49. buffer[offset + 3] = (value >>> 24) & 0xff;
  50. }
  51. }
  52. /** 从 buffer 的 offset 处读取 4 字节无符号整数 */
  53. export function bytesToNumber(
  54. buffer: Uint8Array,
  55. offset: number,
  56. endian: Endian = Endian.BE
  57. ): number {
  58. if (endian === 'be') {
  59. return (
  60. ((buffer[offset]! << 24) |
  61. (buffer[offset + 1]! << 16) |
  62. (buffer[offset + 2]! << 8) |
  63. buffer[offset + 3]!) >>>
  64. 0
  65. );
  66. }
  67. return (
  68. (buffer[offset]! |
  69. (buffer[offset + 1]! << 8) |
  70. (buffer[offset + 2]! << 16) |
  71. (buffer[offset + 3]! << 24)) >>>
  72. 0
  73. );
  74. }
  75. /** 将 UTF-8 字符串转为二进制 */
  76. export function stringToBytes(str: string): Uint8Array {
  77. return UTF8_ENCODER.encode(str);
  78. }
  79. /** 将 UTF-8 二进制转为字符串 */
  80. export function bytesToString(bytes: Uint8Array): string {
  81. return UTF8_DECODER.decode(bytes);
  82. }