出于好奇,二进制代码究竟是如何转换成字母的?我知道有些网站会自动将二进制文件转换为单词,但我想了解二进制代码在转换为字母之前经过的具体中间步骤.
Sha*_*ais 21
这是一种将二进制数转换为ASCII字符的方法,这种方法通常很简单.
1 - 将每4个二进制数字转换为一个十六进制数字.
这是二进制到十六进制的转换图表:
0001 = 1
0010 = 2
0011 = 3
0100 = 4
0101 = 5
0110 = 6
0111 = 7
1000 = 8
1001 = 9
1010 = a (the hex number a, not the letter a)
1011 = b
1100 = c
1101 = d
1110 = e
1111 = f
Run Code Online (Sandbox Code Playgroud)
(十六进制数字a到f是十进制数字10到15.这是十六进制或"基数16" - 而不是每个数字能够代表10个不同的数字[0 - 9],如十进制或"基数10"是的,每个数字代替能够代表16个不同的数字[0 - f].)
一旦知道该图表,将任何二进制数字字符串转换为十六进制数字字符串很简单.
例如,
01000100 = 0100 0100 = 44 hex
1010001001110011 = 1010 0010 0111 0011 = a273 hex
Run Code Online (Sandbox Code Playgroud)
很简单吧?将任意长度的二进制数转换为其十六进制等效值是一件简单的事情.
(这是因为十六进制是16的基数,二进制是2的基数,16是2的4次幂,所以需要4个二进制数来制作1个十六进制数.另一方面,10不是2的幂,所以我们几乎不能轻易地将二进制转换为十进制.)
2 - 将十六进制数字串分成对.
将数字转换为ASCII时,每2个十六进制数字就是一个字符.因此,将十六进制字符串分成两组数字.
您可以将像这样的十六进制数分割为6对,如下所示:
7340298b392 = 07 34 02 98 b3 92
Run Code Online (Sandbox Code Playgroud)
(注意我前面加了0,因为我有一个奇数个十六进制数字.)
这是6对十六进制数字,所以它将是6个字母.(除非我马上知道98,b3和92不是字母.我会在一分钟内解释原因.)
3 - 将每对十六进制数字转换为十进制数字.
通过将左数字的(十进制等效值)乘以16并添加第二个来完成此操作.
例如,b3十六进制= 11*16 + 3,即110 + 66 + 3,即179.(十六进制为十进制11.)
4 - 将十进制数转换为ASCII字符.
现在,要获得十进制数字的ASCII字母,请记住,在ASCII中,65是大写的'A',而97是小写的'a'.
那封信是什么字母68?
68是大写字母的第四个字母,对吗?
65 = A,66 = B,67 = C,68 = D.
所以68是'D'.
你取十进制数,如果数字小于97则减去64表示大写字母,如果数字是97或更大,则减去96表示小写字母,这是与那组2个十六进制数字相关联的字母表的字母数.
或者,如果你不害怕一点点简单的十六进制算术,你可以跳过第3步,直接从十六进制转到ASCII,例如记住,
hex 41 = 'A'
hex 61 = 'a'
Run Code Online (Sandbox Code Playgroud)
因此,对于大写字母减去40十六进制,对于小写字母减去60十六进制,并将左边的数字转换为十进制以获得字母数字.
例如
01101100 = 6c, 6c - 60 = c = 12 decimal = 'l'
01010010 = 52, 52 - 40 = 12 hex = 18 decimal = 'R'
Run Code Online (Sandbox Code Playgroud)
(当这样做时,记住'm'(或'M')是字母表中的13个字母是有帮助的.所以你可以从13开始向上或向下计数以找到一个更接近中间而不是任何一端的字母. )
我曾经在衬衫上看到过这件事,并且能够在我脑海里读到它:
01000100
01000001
01000100
Run Code Online (Sandbox Code Playgroud)
我是这样做的:
01000100 = 0100 0100 = 44 hex, - 40 hex = ucase letter 4 = D
01000001 = 0100 0001 = 41 hex, - 40 hex = ucase letter 1 = A
01000100 = 0100 0100 = 44 hex, - 40 hex = ucase letter 4 = D
Run Code Online (Sandbox Code Playgroud)
这件衬衫上写着"DAD",我认为它有点酷,因为它是由一名孕妇购买的.她的丈夫一定是个像我一样的极客.
我怎么知道92,b3和98不是字母?
因为小写'z'的ASCII码是96 + 26 = 122,十六进制是7a.7a是字母的最大十六进制数.任何大于7a的东西都不是字母.
这就是你如何做到这一点.
计算机程序如何做到这一点?
对于每组8个二进制数字,将其转换为数字,并在ASCII表中查找.
(这是一个非常明显和直接的方式.一个典型的程序员可能会在几分钟的时间内想到10或15种其他方式.细节取决于计算机语言环境.)
Ray*_*oal 20
假定由"二进制代码"您"字母"的意思只是普通的旧数据(字节的比特序列,或),并且你的意思的字符,答案是在两个步骤.但首先是一些背景知识.
好的,现在这里有两个步骤:
数据(如果是文本的)必须以某种方式伴随字符编码,例如UTF-8,Latin-1,US-ASCII等.每个字符编码方案都非常详细地指定字节序列如何被解释为代码点(和相反,如何将码点编码为字节序列).
一旦字节序列被解释为代码点,就会有你的字符,因为每个字符都有一个特定的代码点.
几个笔记:
换句话说,并非每个字节序列都意味着文本.
你的意思是转换011001100110111101101111
→ foo
,例如?你只需要二进制流,将其分割成独立的字节(01100110
,01101111
,01101111
)和查找的ASCII对应于给定数量的字符.例如,01100110
十进制为102,代码为102的ASCII字符为f
:
$ perl -E 'say 0b01100110'
102
$ perl -E 'say chr(102)'
f
Run Code Online (Sandbox Code Playgroud)
(看看chr
函数的作用.)你可以推广这个算法,每个字符和不同的编码有不同的位数,这一点保持不变.