编码学习的笔记

密码学从古典密码的替换、置换到机械密码再到现代密码学,这是个漫长的过程。
最近看了一本《编码:隐藏在计算机软硬件背后的语言》,对编码有了一些体会,做个笔记。(笔记部分选取书内,)

前言

先来个小彩蛋
记事本输入“联通”,然后保存,再打开,发现乱码,大概这个样子
编码学习的笔记
而“移动”重复这样操作就没有这种情况,戏称为“联通不如移动”。

原因是:
而这种情况是因为windows默认编码是GB2312,“联通”的联GB2312编码为\uc1aa,二进制为110000110101010,是按八位一组与UTF8的编码对应,使得windows误认为是UTF-8的文件。

古典密码CTF上并不是感觉很让人有什么兴趣,毕竟工具多基本上就能出来,但CTF不过是竞赛,与真实世界的模拟还有一定距离,在密码学划了一段时间水后,找到了一些好的资料,蛮有意义。
本质上来说,编码更多是的交流,而不是加密保护机密,比如GBK2312的汉语编码,在现在加密更多的是现代密码学。

摩尔斯密码(Morse code)

又称为莫斯密码(翻译问题)
编码学习的笔记
只有点(bot)和划(dash)的古典密码,应用上有很多替代的方式,比如0和1代替点和划线,中间用/或者空格代替,又或是音频里面其中一个声道的电平可以用来制作摩尔斯密码。
特点:

  • 只有两个字符

  • 字符间隔:“.”为1t,“———”为3t,两个之间1t,字符间3t,字间7t。

    附上一个快速记下摩尔斯密码的树形图。(原图太模糊,重新做了一个)
    编码学习的笔记

进制的转换

2进制:Binary
8进制:Octal
10进制:Decimal
16进制:Hexadecimal
顾名思义,二进制每个位数为0-1,八进制即为0-7,16进制为0-f(其中a-f代表10-15)。

简单的计算过程:
二进制到十进制 如10010,

10010=1×24+0×23+0×22+1×21+0×20 10010=1\times2^4+0\times2^3+0\times2^2+1\times2^1+0\times2^0
二进制到十六机制 如10010010

10010010=1001×24+0010×20=1001×16+0010×1=(1×23+0×22+0×21+1×20)×16+(1×21)=9×16+2=146 10010010=1001\times2^4+0010\times2^0 =1001\times16+0010\times1 =(1\times2^3+0\times2^2+0\times2^1+1\times2^0)\times16+(1\times2^1) =9\times16+2=146

诸如此类,根据这种方法即可简单进行手动的进制转换。

关于二进制
对于计算机来说,二进制便于快速计算,在计算机基础或者计算机组成原理有介绍,不再记录。推广而言,图片的黑白色、灯泡的开关、声音信号的两种电平等等均可是其妙用,下面的条形码也是一种应用。

条形码

条形码常用于超市等等地方,作为购物凭证使用,
采用了UPC、Code 3等码制,这里介绍UPC(通用产品代码)。
编码学习的笔记
上图为例,实际上有用的只有其中的一条窄带,
编码学习的笔记
窄带一般包括粗细成比例的黑条和空隙。
黑条即为若干个1,空隙为若干个0.
编码学习的笔记
结构介绍

  1. 101 护线:辅助扫描仪定位,亦可知单个比特的黑条和空隙的宽度。

  2. 左半部分的数字:六组每组7个比特位的字符串,

  3. 01010 中间的护线:内置式检错码,防止被篡改或错印,

  4. 右半部分的数字:六组每组7个比特位的字符串

  5. 101 最右边的护线:类似于最左边的护线,辅助反向扫描。
    参考下面进行解码,
    编码学习的笔记
    编码学习的笔记
    解码后会得到0 51000 01251 7,与条形码底部数字相同,(当然是为了防止条形码损坏拉)。
    继续解码

  6. 0 第一个数字,数字系统字符 0表示规范的UPC解码,不同重量的货物为2,订单、票卷UPC为5。

  7. 51000 制造商代码,

  8. 7 最后一个,模校验字符 通过前面11位计算得到

    前面11个数字用字母代替为A BCDEF GHIJK
    X=3×(A+C+E+G+I+K)+(B+D+F+H+J) X=3\times(A+C+E+G+I+K)+(B+D+F+H+J)

    紧邻X并大于X的10的整数倍-X得到模校验字符

有趣的地方
原书提到用摩尔斯电码表示UPC代码,如“Hi,there”就相当于
编码学习的笔记
,一个很有意思的地方。

逻辑

  • +表示or,×表示and,1-表示not

关于计算机的二进制计算原理

基于一个仅能计算二进制加法的机器,如何能计算减法、乘法等等呢?

先通过逻辑门电路构建与、或、非,输出根据数值位置分为进位输出和和输出。
减法通常来说需要使用借位的方法,高位去1,
但是计算机来说,很难实现,所以相对于加法采用了不同的方法,

  • 253-176相当于253-176+999+1-1000,运行时为253+(999-176)+1-1000,
  • 176-253相当于999-253+176-999,
  • 二进制时用全为1的数代替即可,
  • 对于负的二进制来说,和计算机基础或者计算机组成原理一样,去一个最高位为符号位,只要确定最高有多少位即可,通过补数计算,相当于-128和127实际上在二进制里面只差了1而已。
  • 计算某个数的负数二进制简单办法:先表示正数二进制,然后去反码然后加1。
    如此构成了一个能计算加法和减法的机器,一个痛点是在不确定为无符号数还是有符号位数时,你无法确定一个二进制数到底是多少,比如1001既可以是9也可能是-7。

字符与进制

八个二进制数相当于两个十六进制数,相当于一个字符,也就是ASCII码,好像所有人都用它,但是实际上IBM的系统采用的就不一样,为EBCDIC字符。后面还有1988年研究的Unicode编码,采用了16位编码,表示65536个不同的字节,0000h—007Fh与ASCII一致,后面收录了很多其他国家的标准。而且Unicode相对于ASCII码进行编码会存在占用更多内存,也不少一个可以忽略的事实。

后面的章节

虽然后面计算机历史很有意思,但是太过于繁琐,了解即可,不再赘述,再后面就是汇编之类,直接参考王爽的汇编语言更好。

结束语

你可能从这本书学到很高级的编码,但是更多是学习对于编码还有计算机的理解。

[1] (美)查尔斯•佩措尔德著. 编码:隐匿在计算机软硬件背后的语言[M].左飞译. 电子工业出版社
[2] (日)结城浩著. 程序员的数学[M].管杰译. 人民邮电出版社

相关文章: