我目前开始使用DER(杰出编码规则)编码,并且在理解整数编码方面遇到问题。
在参考文档https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf中,此编码的定义如下:
8.3.1整数值的编码必须是原始的。内容字节应由一个或多个字节组成。
8.3.2如果整数值编码的内容八位位组包含多个八位位组,则第一个八位位组的位和第二个八位位组的位8:
不能全都是一个;和
不能全部为零。
注意–这些规则确保始终以尽可能最小的八位字节数编码整数值。
8.3.3内容八位位组应为等于整数值的二进制补码二进制数,由第一个八位位组的第8至1位,第二个八位位组的第8至1位,后跟第8位至第8位组成每个八位位组中的1个依次到内容八位位组的最后一个八位位组,并包括该八位位组的最后一个八位位组。
在另一个站点https://docs.microsoft.com/en-us/windows/desktop/seccertenroll/about-integer上,说明了对于二进制表示形式以1开头的正数,在其前面添加了零字节。以前关于stackoverflow的问题的答案中也提到了这一点:ASN Basic Encoding Rule of an integer。
不幸的是,从这些答案中,我看不到如何从参考文档的规则中推导出后一条指令。
例如,如果我想对数字128进行编码,为什么我不能这样做
[标签字节] [长度字节] 10000000?
我知道正确的编码应该是[标签字节] [长度字节] 00000000 10000000,但是上面的变体会伤害哪种条件?可能与两者的补码有关,但不是128的两个补码再加上10000000吗?
希望您能帮助我理解为什么Microsoft网站上的描述与原始定义相同。谢谢。
答案 0 :(得分:0)
Two's complement规则(8.3.3)指出,如果设置了第一个(最低索引)内容字节的高位,则该数字为负。
02 01 80
的内容为0b1000_0000
。由于高位已设置,因此数字为负。
翻转所有位(0b0111_1111
),然后加一个:0b1000_0000
;表示它代表负数128。
对于一个退化程度较小的示例,0b1000_0001
=> 0b0111_1110
=> 0b0111_1111
,表明0x81
为负127。
对于数字(正)127,由于未设置高位,因此该数字被解释为正,因此内容仅为0b0111_1111
或0x7F
,导致{{1} }