readInt16BE 和 readInt16LE 的区别

放张图,如果不出所料,大家应该也不知道什么意思。毕竟写个页面为毛和进制扯上关系了。这是个扩展出来的话题,要不是看getCookies 的 bug,我也不会去查阅了解这个文章标题中 2 个规范有什么区别。

下面就慢慢学习吧?(以下内容大概阅读 15 分钟)

端(endian)的起源

“endian”一词来源于十八世纪爱尔兰作家乔纳森·斯威夫特(Jonathan Swift)的小说《格列佛游记》(Gulliver’s Travels)。小说中,小人国为水煮蛋该从大的一端(Big-End)剥开还是小的一端(Little-End)剥开而争论,争论的双方分别被称为“大端派”和“小端派”。以下是 1726 年关于大小端之争历史的描述:

“我下面要告诉你的是,Lilliput 和 Blefuscu 这两大强国在过去 36 个月里一直在苦战。战争开始是由于以下的原因:我们大家都认为,吃鸡蛋前,原始的方法是打破鸡蛋较大的一端,可是当今皇帝的祖父小时候吃鸡蛋,一次按古法打鸡蛋时碰巧将一个手指弄破了。因此他的父亲,当时的皇帝,就下了一道敕令,命令全体臣民吃鸡蛋时打破鸡蛋较小的一端,违令者重罚。老百姓们对这项命令极其反感。历史告诉我们,由此曾经发生过 6 次叛乱,其中一个皇帝送了命,另一个丢了王位。这些叛乱大多都是由 Blefuscu 的国王大臣们煽动起来的。叛乱平息后,流亡的人总是逃到那个帝国去寻求避难。据估计,先后几次有 11000 人情愿受死也不肯去打破鸡蛋较小的一端。关于这一争端,曾出版过几百本大部著作,不过大端派的书一直是受禁的,法律也规定该派任何人不得做官。”
— 《格列夫游记》 第一卷第 4 章 蒋剑锋(译)

什么是 Big Endian、Little Endian

Big Endian:低地址存放最高有效字节
示例中,最高位字节是 0x0A 存储在最低的内存地址处。下一个字节 0x0B 存在后面的地址处。正类似于十六进制字节从左到右的阅读顺序。

最低位字节是 0x0D 存储在最低的内存地址处。后面字节依次存在后面的地址处。
Little Endian:低地址存放最低有效字节

那和 node 有毛关系?

下面几个 api 熟悉么?Buffer 看见过吧?

node 玩了许久,其实也就是调调接口,底层 api 接触的不多,如果不再查漏补缺可能来年就要被淘汰了,出去找工作都不好意思说有 node 经验。

通过一个例子,来看下:

1
2
3
//请问,分别输出多少?
Buffer.from('000A', 'hex').readUInt16BE(0);
Buffer.from('000A', 'hex').readUInt16LE(0);

开始解题:

  1. 先看下 Buffer.from 什么意思?
    // 根据编码,解析 string,返回一个数组 buffer
    Buffer.from(str[, encoding]) returns a new Buffer containing a copy of the provided string.
1
Buffer.from('000A', 'hex');//<Buffer 00 0a>
  1. readUInt16XX 到底怎么算?
    看 node api 描述:readUInt16BE() returns big endian, readUInt16LE() returns little endian。
    好了,看到这个就大致明白开头恶补的端的知识点(大端:顺着取位,小端:倒着取位)
    那么,根据前面的 buffer data,有以下计算过程:
    00(16 进制) -> 0(10 进制) -> 00000000(2 进制)(8bit(位)=1byte(字节)=1B)
    0a -> 10(10) -> 00001010(2)
    结果就非常好算了:
    readUInt16BE(0) = 00000000 00001010 = 10
    readUInt16LE(0) = 00001010 00000000 = 2560

实际应用

那就练下?看下某个库中 p 的值是怎么在实际运用的

【长按关注】看看↓↓↓?
Eminoda wechat
【前端雨爸】分享前端技术实践,持续输出前端技术文章
欢迎留言,评论交流,一起讨论前端问题
📢 因为是开源博客,为避免 Gitalk授权 带来的 安全风险,也可访问