Endianness(字节序)
字节序,或字节顺序("Endian"、"endianness" 或 "byte-order"),描述了计算机如何组织字节,组成对应的数字。 每个内存存储位置都有一个索引或地址。每一 字节可以存储一个 8位数字(即 介于0x00 和 0xff 之间 0~255),因此,你必须保留不止一个字节来储存一个更大的数字。
- little-endian 现在,大部分需占用多个字节的数字排序方式是 little-endian(译者注:可称小字节序、低字节序,即低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。与之对应的 big-endian 排列方式相反,可称大字节序、高字节序),所有的英特尔处理器都使用 little-endian。little-endian 的意思是使用低位储存更重要的信息,least-to-most-significant(最低有效(least significant)字节取第一个位置,或者说,地址最低的位置),可类比欧洲通用的日期书写方式(例如,31 December 2050。译者注:年份是最重要的,月份其次,日期最后)。
- big-endian 自然, big-endian 是相反的顺序, 可类比 ISO 日期格式(例如 2050-12-31)。big-endian 通常被称作"网络字节顺序"("network byte order"), 因为互联网标准通常要求数据使用 big-endian 存储,从标准 Unix 套接字(socket)层开始,一直到标准化网络的二进制数据结构。此外,老式 Mac 计算机的 68000 系列 和 PowerPC(译者注:IBM 与 Apple 公司联合生产的个人台式机)微处理器曾使用 big-endian。
举个例子,用不同字节序存储数字 0x12345678(即十进制中的 305 419 896):
- little-endian:0x78 0x56 0x34 0x12
- big-endian:0x12 0x34 0x56 0x78
- mixed-endian(文物,非常罕见):0x34 0x12 0x78 0x56
说明:本人理解的字节高位和低位是个方向问题,高位字节从左往右;低位字节从右往左。内存是从左往右,内地地址依次增加一,故文中高地址端指的后面。
Base64
Base64是一组相似的二进制到文本(binary-to-text)的编码规则,使得二进制数据在解释成radix-64的表现形式后能够用ASCII字符串的格式表示出来。 在JavaScript中,有2个函数分别用来处理解码和编码base64 字符串:
- atob() 解码
- btoa() 编码
let encodedData = window.btoa("Hello, world"); // SGVsbG8sIHdvcmxk
let decodedData = window.atob(encodedData); // "Hello, world")
原码/反码/补码/整形/浮点数
- 原码 直接将二进制按照正负数的形式翻译成二进制就可以。
- 反码 将原码的符号位不变,其他位依次按位取反就可以得到了。
- 补码 反码+1就得到补码。
- 整型 以2进制本数的补码存在的;
- 浮点数 32位(单精度float):对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。 64位(双精度float):对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M。
JS API
- ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。 ArrayBuffer 不能直接操作,而是要通过类型数组对象或 DataView 对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。
- SharedArrayBuffer 对象用来表示一个通用的,固定长度的原始二进制数据缓冲区,类似于 ArrayBuffer 对象,它们都可以用来在共享内存(shared memory)上创建视图。与 ArrayBuffer 不同的是,SharedArrayBuffer 不能被分离。
- Uint8Array 数组类型表示一个8位无符号整型数组,创建时内容被初始化为0。创建完后,可以以对象的方式或使用数组下标索引的方式引用数组中的元素。
- Uint8ClampedArray (8位无符号整型固定数组) 类型化数组表示一个由值固定在0-255区间的8位无符号整型组成的数组; 如果你指定一个在 [0,255] 区间外的值,它将被替换为0或255;如果你指定一个非整数,那么它将被设置为最接近它的整数。(数组)内容被初始化为0。一旦(数组)被创建,你可以使用对象的方法引用数组里的元素,或使用标准的数组索引语法(即使用方括号标记)。
- Uint16Array 数组类型表示一个16位无符号整型数组,创建时内容被初始化为0。创建完后,可以以对象的方式或使用数组下标索引的方式引用数组中的元素。
- Uint32Array 数组类型表示一个32位无符号整型数组,创建时内容被初始化为0。创建完后,可以以对象的方式或使用数组下标索引的方式引用数组中的元素。
- Int8Array 类型数组表示二进制补码8位有符号整数的数组。内容初始化为0。 一旦建立,你可以使用对象的方法引用数组中的元素,或使用标准数组索引语法( 即,使用括号注释)。
- Int16Array 类型数组表示二进制补码16位有符号整数的数组。内容初始化为0。 一旦建立,你可以使用对象的方法引用数组中的元素,或使用标准数组索引语法( 即,使用括号注释)。
- Int32Array 类型数组表示二进制补码32位有符号整数的数组。内容初始化为0。 一旦建立,你可以使用对象的方法引用数组中的元素,或使用标准数组索引语法( 即,使用括号注释)。
- Float32Array 类型数组代表的是平台字节顺序为32位的浮点数型数组(对应于 C 浮点数据类型) 。 如果需要控制字节顺序, 使用 DataView 替代。其内容初始化为0。一旦建立起来,你可以使用这个对象的方法对其元素进行操作,或者使用标准数组索引语法 (使用方括号)。
- Float64Array 类型数组代表的是平台字节顺序为64位的浮点数型数组(对应于 C 浮点数据类型) 。 如果需要控制字节顺序, 使用 DataView 替代。其内容初始化为0。一旦建立起来,你可以使用这个对象的方法对其元素进行操作,或者使用标准数组索引语法 (使用方括号)。
- DataView 视图是一个可以从 ArrayBuffer 对象中读写多种数值类型的底层接口,使用它时,不用考虑不同平台的字节序问题。
| Type | Value Range | Size in bytes | Description | Web IDL type | Equivalent C type |
|---|---|---|---|---|---|
| Int8Array | -128 to 127 | 1 | 8-bit two's complement signed integer | byte | int8_t |
| Uint8Array | 0 to 255 | 1 | 8-bit unsigned integer | octet | uint8_t |
| Uint8ClampedArray | 0 to 255 | 1 | 8-bit unsigned integer (clamped) | octet | uint8_t |
| Int16Array | -32768 to 32767 | 2 | 16-bit two's complement signed integer | short | int16_t |
| Uint16Array | 0 to 65535 | 2 | 16-bit unsigned integer unsigned | short | uint16_t |
| Int32Array | -2147483648 to 2147483647 | 4 | 32-bit two's complement signed integer | long | int32_t |
| Uint32Array | 0 to 4294967295 | 4 | 32-bit unsigned integer unsigned | long | uint32_t |
| Float32Array | 1.2x10-38 to 3.4x1038 | 4 | 32-bit IEEE floating point number ( 7 significant digits e.g. 1.1234567) unrestricted | float | float |
| Float64Array | 5.0x10-324 to 1.8x10308 | 8 | 64-bit IEEE floating point number (16 significant digits e.g. 1.123...15) unrestricted | double | double |
| BigInt64Array | -263 to 263-1 | 8 | 64-bit two's complement signed integer | bigint | int64_t (signed long long) |
| BigUint64Array | 0 to 264-1 | 8 | 64-bit unsigned integer | bigint | uint64_t (unsigned long long) |