【发布时间】:2011-07-26 07:12:43
【问题描述】:
出于好奇,二进制代码究竟是如何转换成字母的?我知道有些网站会自动为您将二进制转换为单词,但我想了解二进制代码在转换为字母之前所经历的具体中间步骤。
【问题讨论】:
-
二进制码是什么意思?你的意思是从一个ASCII码到对应的字母?
标签: binary
出于好奇,二进制代码究竟是如何转换成字母的?我知道有些网站会自动为您将二进制转换为单词,但我想了解二进制代码在转换为字母之前所经历的具体中间步骤。
【问题讨论】:
标签: binary
这是一种将二进制数转换为 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
(十六进制数字 a 到 f 是十进制数字 10 到 15。这就是十六进制或“base 16”的含义 - 而不是每个数字能够代表 10 个不同的数字 [0 - 9],例如十进制或“以 10 为底”,每个数字可以代表 16 个不同的数字 [0 - f]。)
一旦您知道该图表,将任何二进制数字字符串转换为十六进制数字字符串都很简单。
例如,
01000100 = 0100 0100 = 44 hex
1010001001110011 = 1010 0010 0111 0011 = a273 hex
够简单吧?将任意长度的二进制数转换为等价的十六进制数是一件简单的事情。
(这是有效的,因为十六进制是以 16 为底,二进制是以 2 为底,而 16 是 2 的 4 次方,因此需要 4 个二进制数字才能形成 1 个十六进制数字。另一方面,10 不是 2 的幂,所以我们不能轻易地将二进制转换为十进制。)
2 - 将十六进制数字字符串拆分成对。
将数字转换为 ASCII 时,每 2 个十六进制数字为一个字符。因此,将十六进制字符串分成 2 位数字组。
您可以将像 7340298b392 这样的十六进制数拆分为 6 对,如下所示:
7340298b392 = 07 34 02 98 b3 92
(注意我在前面加了一个 0,因为我有奇数个十六进制数字。)
这是 6 对十六进制数字,所以它将是 6 个字母。 (除了我马上就知道 98、b3 和 92 不是字母。我会在一分钟内解释原因。)
3 - 将每对十六进制数字转换为十进制数字。
通过将左边的数字(的十进制等价物)乘以 16,然后加上第二个来做到这一点。
例如,b3 hex = 11*16 + 3,即 110 + 66 + 3,即 179。 (b hex 是十进制的 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'
因此,大写字母减去 40 十六进制或小写字母减去 60 十六进制,然后将剩下的转换为十进制以得到字母数字。
例如
01101100 = 6c, 6c - 60 = c = 12 decimal = 'l'
01010010 = 52, 52 - 40 = 12 hex = 18 decimal = 'R'
(这样做时,记住“m”(或“M”)是字母表中的第 13 个字母会很有帮助。因此,您可以从 13 向上或向下数,以找到更靠近中间的字母而不是任何一端。)
我曾经在一件衬衫上看到这个,并且能够在我的脑海中阅读它:
01000100
01000001
01000100
我是这样做的:
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
这件衬衫上写着“DAD”,我觉得这很酷,因为它是由一位孕妇购买的。她的丈夫一定是个像我一样的怪胎。
我怎么马上就知道 92、b3 和 98 不是字母?
因为小写“z”的 ASCII 码是 96 + 26 = 122,十六进制是 7a。 7a 是字母的最大十六进制数。任何大于 7a 的都不是字母。
这就是你作为人类的方式。
计算机程序是如何做到的?
对于每组 8 个二进制数字,将其转换为数字,并在 ASCII 表中查找。
(这是一种非常明显和直接的方法。一个典型的程序员可能会在几分钟内想到 10 或 15 种其他方法。具体取决于计算机语言环境。)
【讨论】:
01000100 视为 2^6+2^2=68。
假设“二进制代码”是指普通的旧数据(位或字节的序列),而“字母”是指字符,那么答案分两步。但首先,一些背景知识。
好的,现在是两个步骤:
如果是文本数据,则必须以某种方式伴随着 字符编码,例如 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
(See what the chr function does.) 你可以推广这个算法,每个字符有不同的位数和不同的编码,点保持不变。
【讨论】:
-e 命令行可用于输入一行程序。如果给出 -e,Perl 将不会在参数列表中查找文件名。可以给出多个 -e 命令来构建多行脚本。确保在正常程序中使用分号。 -E 命令行的行为与 -e 类似,只是它隐式启用所有可选功能(在主编译单元中)。见功能。 perldoc.pl/perlrun#-e-commandline
只用你的脑袋就可以极快地读取二进制 ASCII 字符:
字母以前导位 01 开头。位 3 为小写打开 (1),大写关闭 (0)。扫描以下第 4-8 位以查找第一个打开的位,并从该字符串中的同一索引中选择起始字母:“PHDBA”(想想 P.H.D.,文学学士)。例如。 1xxxx = P、01xxx = H 等。然后将剩余的位转换为整数值(例如 010 = 2),然后从起始字母开始计数那么多字母。例如。 01001010 => H+2 = J.
【讨论】:
http://www.roubaixinteractive.com/PlayGround/Binary_Conversion/The_Characters.asp 它只是看起来在这里......(不是在这里,但它有一张桌子)。
一个字节有 8 位。一个字节可以是一个符号。一位是打开还是关闭。
【讨论】:
为什么不直接将 010010001001001 分成两个位,每个位 8 个字母(01001000、01001001)。然后发布权力
01001000。 01001001。
前 8 个忽略他们确定是否为大写字母的前三个,从右到左执行 2 的幂 (2^1, 2^2 2^3 2^4 2^5)。然后把所有的加起来,只有一个,它=8,字母表中的八个字母是h,所以我们的第一个是字母h,在另一个上试试
【讨论】: