二进制代码究竟是如何转换成字母的?

use*_*510 27 binary

出于好奇,二进制代码究竟是如何转换成字母的?我知道有些网站会自动将二进制文件转换为单词,但我想了解二进制代码在转换为字母之前经过的具体中间步骤.

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

假定由"二进制代码"您"字母"的意思只是普通的旧数据(字节的比特序列,或),并且你的意思的字符,答案是在两个步骤.但首先是一些背景知识.

  • 角色只是一个命名符号,如"LATIN CAPITAL LETTER A"或"GREEK SMALL LETTER PI"或"BLACK CHESS KNIGHT".不要将字符(抽象符号)与字形(字符图片)混淆.
  • 字符集是一组特定的字符,其中的每一个是用特殊号码相关联的,被称为其编码点.要查看Unicode字符集中的代码点映射,请参阅http://www.unicode.org/Public/UNIDATA/UnicodeData.txt.

好的,现在这里有两个步骤:

  1. 数据(如果是文本的)必须以某种方式伴随字符编码,例如UTF-8,Latin-1,US-ASCII等.每个字符编码方案都非常详细地指定字节序列如何被解释为代码点(和相反,如何将码点编码为字节序列).

  2. 一旦字节序列被解释为代码点,就会有你的字符,因为每个字符都有一个特定的代码点.

几个笔记:

  • 在某些编码中,某些字节序列根本不对应于任何代码点,因此您可能会出现字符解码错误.
  • 在某些字符集中,存在未使用的代码点,也就是说,它们根本不对应于任何字符.

换句话说,并非每个字节序列都意味着文本.


zou*_*oul 7

你的意思是转换011001100110111101101111foo,例如?你只需要二进制流,将其分割成独立的字节(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函数的作用.)你可以推广这个算法,每个字符和不同的编码有不同的位数,这一点保持不变.