【问题标题】:How exactly does binary code get converted into letters?二进制代码究竟是如何转换成字母的?
【发布时间】:2011-07-26 07:12:43
【问题描述】:

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

【问题讨论】:

  • 二进制码是什么意思?你的意思是从一个ASCII码到对应的字母?

标签: binary


【解决方案1】:

这是一种将二进制数转换为 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。
  • 有趣。让我们看看,我猜最右边的数字是 2^0,所以 2^6 是最右边的第 7 个数字。 2^6 是.. 2,4,8,16,32,64.. 而 2^2 是 2*2 即 4,所以,对,应该是 68。ASCII 码是 8 位宽,所以我猜猜如果您知道 2 到 7 位的幂(因为 01111010 是最大的字母),那么该方法可能足够实用,尽管像 01011010 这样的方法可能比您只知道 4 位的十六进制数字需要更长的时间; 0101 = 5,1010 = A,所以 5A。转换为字母:0x5A - 0x40(大写字母)= 0x1A = 16 + 10 = 26(大写字母)='Z'。
  • 如果你真的更喜欢用十进制工作,我想实际上你可以知道十进制值到 4 位,对于每组 8 位,将左边的集合乘以 16 并添加第二个放。所以 0101:1010 = 5:10 = 5 * 16 + 10 = 50 + 30 + 10 = 90。如果你知道 64 是要减去大写字母的十进制数,那么你会得到 26('Z')。跨度>
【解决方案2】:

假设“二进制代码”是指普通的旧数据(位或字节的序列),而“字母”是指字符,那么答案分两步。但首先,一些背景知识。

  • 字符只是一个命名符号,如“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. 一旦字节序列被解释为代码点,你就有了你的字符,因为每个字符都有一个特定的代码点。

几个注意事项:

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

换句话说,并不是每个字节序列都意味着文本。

【讨论】:

    【解决方案3】:

    您的意思是转换011001100110111101101111foo,例如?您只需获取二进制流,将其拆分为单独的字节(011001100110111101101111)并查找与给定数字对应的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
    【解决方案4】:

    只用你的脑袋就可以极快地读取二进制 ASCII 字符:

    字母以前导位 01 开头。位 3 为小写打开 (1),大写关闭 (0)。扫描以下第 4-8 位以查找第一个打开的位,并从该字符串中的同一索引中选择起始字母:“PHDBA”(想想 P.H.D.,文学学士)。例如。 1xxxx = P、01xxx = H 等。然后将剩余的位转换为整数值(例如 010 = 2),然后从起始字母开始计数那么多字母。例如。 01001010 => H+2 = J.

    【讨论】:

    • 哇,这太酷了!一些真正聪明的人想出了这个。我敢打赌这已经通过高中和大学的口口相传,现在我是多年来最后一个听到它的人了,哈哈。在这里,它可能会更彻底地进行布局和解释,但是。我认为这可能比我提出的方法好一点。
    • 如果你在大学里错过了这个,我也错过了。我只是在尝试解码带有大量二进制文件的 T 恤时注意到了这种模式。顺便说一句,感谢您在答案中解释二进制部分。我只是假设一些知识,因为它在这个页面上。 :-)
    【解决方案5】:

    http://www.roubaixinteractive.com/PlayGround/Binary_Conversion/The_Characters.asp 它只是看起来在这里......(不是在这里,但它有一张桌子)。

    一个字节有 8 位。一个字节可以是一个符号。一位是打开还是关闭。

    【讨论】:

      【解决方案6】:

      为什么不直接将 010010001001001 分成两个位,每个位 8 个字母(01001000、01001001)。然后发布权力

      01001000。 01001001。

      前 8 个忽略他们确定是否为大写字母的前三个,从右到左执行 2 的幂 (2^1, 2^2 2^3 2^4 2^5)。然后把所有的加起来,只有一个,它=8,字母表中的八个字母是h,所以我们的第一个是字母h,在另一个上试试

      【讨论】:

        猜你喜欢
        • 2010-09-17
        • 2019-11-09
        • 1970-01-01
        • 2013-12-05
        • 2015-08-01
        • 2022-11-29
        • 2014-05-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多