公厕里的二进制究竟写的什么

捉虫大师

共 2098字,需浏览 5分钟

 · 2024-04-11

hello,大家春节好啊,我是小楼。

春节带娃逛公园,在公园厕所里发现了一张有意思的图:

9ed60e15f0a706fe2983a95cae88f5d9.webp

好几种语言写的 “往前一小步,文明一大步”,男同胞应该大部分都看过类似的标语,但这个二进制有点意思。

我把这个图发给一个公务员朋友,他说这个只有你们程序员看得懂,我说我也看不懂。

原来在外行眼里,程序员竟然还能看懂二进制~

回到家后,我在想,这二进制究竟写的啥?难道设计者是程序员?又或许是设计者瞎写的?

为了看懂这段二进制,得先想办法把这段01组成的文本搞出来。

靠肉眼加手敲显然不行,我想到了微信自带的识别文字:

a1cec0382f243e811da67b3b4bb4587e.webp

显然不对,丢了很多。

接着我想到了 OCR,但是搜了一下发现全是接口文档的广告,还需要自己实现,显然不可能为了识别一张图片去开发个程序,于是又继续搜如何提取图片文字,发现了一款微信小程序,试了下,还真就识别出来了

6f114e9ea24674a467735ac30eed5eb8.webp
      
      11100101100100001001000111100101100010011000110111100100101110001000000011100101101100001000111111100110101011011010010100100000111001101001011010000111111001101001100010001110111001001011100010000000111001011010010010100111
111001101010110110100101

看了下,248个0和1的组合,248比较特殊,可以被8整除,斗胆猜测是 ASCII 码,每8位表示一个,于是我简单写了个Go程序验证下:

      
      func TestBinary(t *testing.T) {
 str := "11100101100100001001000111100101100010011000110111100100101110001000000011100101101100001000111111100110101011011010010100100000111001101001011010000111111001101001100010001110111001001011100010000000111001011010010010100111111001101010110110100101"
 for i := 0; i < len(str); i = i + 8 {
  code, _ := strconv.ParseInt(str[i:i+8], 264)
  fmt.Printf("%c"int(code))
 }
}

结果一运行出现了:

6881ab25cb45ec18900d996425a92cdd.webp

这是啥玩意?难道是我代码写错了?

90b6b55f1f8cd07cf31fdd506c92332d.webp

于是我想直接问一下百度,这串二进制如何转换为ASCII码

39504e383a96ab0768b10f505b0e4394.webp

百度丢给我一段 python 代码,虽然我对 py 不太熟,但还是知道怎么运行,于是我把它粘贴到文件里,保存为 test.py 文件,然后执行 python test.py

767ca465776f0af2420371b31177aaba.webp

AI 还真是厉害!

原来这里是对中文的编码,我一直以为是英文。这里应该是 unicode 编码,通常用 UTF-8 来存储 unicode 字符,它是一种变长的存储方式,比较节省空间,使用1~4个字节表示字符,汉字通常是3~4个字节。

那么问题来了,给一串二进制怎么知道字符使用了几个字节表示呢?其实是有个规定:

  • 1字节:0xxx xxxx
  • 2字节:110x xxxx 10xx xxxx
  • 3字节:1110 xxxx 10xx xxxx 10xx xxxx
  • 4字节:1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx

用上面的二进制举例,可以把第一个汉字捞出来:

1110 0101  1001 0000  1001 0001

对应上面规则为3字节,再把固定的前缀去掉,得到unicode编码:

0101 0100 0001 0001

转换为16进制:\u5411,查询下果然是“向”

3b7f647d8da42efb5c45d71cc577fb0c.webp

同理可得其他字符。按照这个逻辑来写代码解析就比较简单了,但 python 的 chr 函数还是有点意思,为什么这么说呢?因为它不是按照我们这个逻辑去解析的,它是固定8位8位地解析,结果也能解析完整。如果把每次调用 chr 的结果都输出,你就会发现它的厉害之处:

7b9055f96a44ca55566a1d53e4fc2141.webp

好了 python 这个彩蛋留给大家去探索,本文到此为止,我们下期再见~

浏览 8
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报