返回介绍

Code

发布于 2025-01-31 22:20:48 字数 8772 浏览 0 评论 0 收藏 0

Code

资讯替换成代号,以代号记载资讯。这些代号称做“码”。

99,3qㄋ姑力 i 读猪,偶会+ Uㄉ!
口以ㄇ?ㄅ口以!
(゚д゚)

程式设计就是将“电脑的工作资讯”替换成“程式码”。

int main() {
    int n = 1 + 1;
    return 0;
}

数学式子也是一种码。大部分人类都不清楚原本的资讯为何。

e + 1 = 0

“二元码 Binary code”,二进位字串,电脑设备所用的码。本章节的主角。

011000100110100101101110011000010111001001111001

“摩斯电码 Morse Code”,战争通讯所用的码。

-- --- .-. ... .

“点字 Braille”,盲人所用的码。

⠃ ⠗ ⠁ ⠊ ⠇ ⠇ ⠑

“条码 Barcode”,包装标示所用的码。知名的条码如:商品的 Code39、书籍的 ISBN、导览的 QR Code。

“International Code of Signals”,船舶所用的码。

“外星人编码”,一根棒子,精准地刻一刀,就能记载世上所有知识。找到刻记的高度,占筷子全长的几分之几,计算小数点后面所有位数,就得到了码。无论要谈什麽,只要刻一刀就好。

UVa 508

Encode / Decode

“编码”,资讯转码。“解码”,码转资讯。

编码 “cat”--->“011000110110000101110100”
解码 “cat”<---“011000110110000101110100” <="" pre="">

资讯和码最好一一对应,让编码与解码不生歧义。只要知道每种码的意义,就能获知原本的资讯。火星文就是一种很不好的码。

文字编码

文字、声音、图像、动作、感受,通通可以编码。以下我们只讨论文字编码──最简单、最基础的编码。

英文变成二元码,是参照“美国资讯交换标准码 ASCII”的规定。ASCII 的设计理念是:拆散英文文字,成为单独的字母、符号,各种不同的字符都有固定的二元码。

ASCII
英文字母 a 变成二元码 01100001,符号=变成二元码 00111101。

繁体中文变成二元码,是参照现时流行的“万国码 Unicode”或者逐渐落寞的“大五码 Big5”。

Unicode
中文字“大”变成二元码 0101100100100111。(十六进位数字 5927)
Big5
中文字“大”变成二元码 1010010001101010。(十六进位数字 a46a)
GB2312
中文字“大”变成二元码 1011010011110011。(十六进位数字 b4f3)

文字编码是以字符为基本单位,从头到尾扫描。

编码。从头到尾扫描文字,每当发现一段文字有其对应的码,就马上换成码。持续扫描下去,让码越接越长。

编码 cat
扫描 c,换成 01100011
扫描 a,换成 01100001
扫描 t,换成 01110100
最后得到 011000110110000101110100

解码。从头到尾扫描码,每当发现一段码有其对应的文字,就马上换成文字。持续扫描下去,让文字越接越长。

解码 011000110110000101110100
扫描 0
扫描 1
扫描 1
……
扫描第 8 个位元 1,发现 01100011 是字母 c 的码,换成 c
……
扫描第 16 个位元 1,发现 01100001 是字母 a 的码,换成 a
……
扫描第 24 个位元 0,发现 01110100 是字母 t 的码,换成 t
最后得到 cat

Fixed-length Code / Variable-length Code

设计码,有两种策略。

“固定长度编码”令每个字符的码一样长。比如 ASCII。

A  00001
B  00010
C  00011
D  00100
⋮    ⋮
Z  11010

“可变长度编码”令各个字符的码不等长。比如 UTF-8。

A  000
B  001
C  0100
D  0101
⋮    ⋮
Z  11111

Fixed-length Code :两个码千万不能相同

当两个码相同,解码将产生歧义。

A  00001
B  00010
C  00001

解码 00001...
扫描前五个位元,得到 00001,可能是 A,也可能是 B。

Variable-length Code:一个码千万不能是另一个码的前缀

当一个码是另一个码的开头,解码将产生歧义。

A  011
B  0111
C  00111

解码 011111...
扫描前三个位元,得到 011,可能是 A。
扫描前四个位元,得到 0111,也可能是 B。

也许你马上联想到 0/1 Knapsack Problem、Sardinas-Patterson Algorithm,不过这不是本篇主旨。

码的长度

二元码的情况下,N 种字符,至少需要 ceil(log₂N) 个位元,才能让每个字符拥有独一无二的码,让解码不生歧义。比如 26 个大写英文字母,26 ≤ 2⁵,至少需 5 个位元。

UVa 444 10878 213 740 10851 739 10921 10415 1590

ASCII

American Standard Code for Information Interchange

ASCII Table
NUL 00000000     00100000   @ 01000000   ` 01100000
SOH 00000001   ! 00100001   A 01000001   a 01100001
STX 00000010   " 00100010   B 01000010   b 01100010
ETX 00000011   # 00100011   C 01000011   c 01100011
EOT 00000100   $ 00100100   D 01000100   d 01100100
ENQ 00000101   % 00100101   E 01000101   e 01100101
ACK 00000110   & 00100110   F 01000110   f 01100110
BEL 00000111   ' 00100111   G 01000111   g 01100111
BS  00001000   ( 00101000   H 01001000   h 01101000
HT  00001001   ) 00101001   I 01001001   i 01101001
LF  00001010   * 00101010   J 01001010   j 01101010
VT  00001011   + 00101011   K 01001011   k 01101011
FF  00001100   , 00101100   L 01001100   l 01101100
CR  00001101   - 00101101   M 01001101   m 01101101
SO  00001110   . 00101110   N 01001110   n 01101110
SI  00001111   / 00101111   O 01001111   o 01101111
DLE 00010000   0 00110000   P 01010000   p 01110000
DC1 00010001   1 00110001   Q 01010001   q 01110001
DC2 00010010   2 00110010   R 01010010   r 01110010
DC3 00010011   3 00110011   S 01010011   s 01110011
DC4 00010100   4 00110100   T 01010100   t 01110100
NAK 00010101   5 00110101   U 01010101   u 01110101
SYN 00010110   6 00110110   V 01010110   v 01110110
ETB 00010111   7 00110111   W 01010111   w 01110111
CAN 00011000   8 00111000   X 01011000   x 01111000
EM  00011001   9 00111001   Y 01011001   y 01111001
SUB 00011010   : 00111010   Z 01011010   z 01111010
ESC 00011011   ; 00111011   [ 01011011   { 01111011
FS  00011100   < 00111100   \ 01011100   | 01111100
GS  00011101   = 00111101   ] 01011101   } 01111101
RS  00011110   > 00111110   ^ 01011110   ~ 01111110
US  00011111   ? 00111111   _ 01011111 DEL 01111111
注:有框框的是特殊字元,没有实际的外型,无法显示在萤幕上。
注:第二排第一个是空白键。
     0   1   2   3   4   5   6   7   8   9   10  11  12  13  14  15
   +----------------------------------------------------------------
0  | NUL SOH STX ETX EOT ENQ ACK BEL BS  HT  LF  VT  FF  CR  SO  SI
16 | DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM  SUB ESC FS  GS  RS  US
32 |     !   "   #   $   %   &   '   (   )   *   +   ,   -   .   /
48 | 0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?
64 | @   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
80 | P   Q   R   S   T   U   V   W   X   Y   Z   [   \   ]   ^   _
96 | `   a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
112| p   q   r   s   t   u   v   w   x   y   z   {   |   }   ~   DEL

ASCII 一共有 128 种字元,每个字元对应的二元码,换成数值刚好就是 0 到 127 的整数。可以想成编号 0 号到编号 127 号。

128 种字元当中,有些字元没有实际的外型,通常作为特殊用途。例如编号 0 号的字元,在 C 程式语言当中用来当作字串的结尾符号。

大部分的字元,在键盘上面都有对应的按键,例如 qwe123`-=等等。少部分的字元,则没有对应的按键,必须预先按住 shift 或者 ctrl 之后才能输入。

ASCII 有英文字母、标点符号、数字、四则运算符号等等,却没有中文字、注音符号、微积分符号、可爱小图示之类的。这是因为当初设计 ASCII 的人,从未想过电脑会普及遍佈全世界,所以只设计了一些简易的符号。

1 byte

早期的中央处理器,一次可以接受 8 bit = 1 byte,因此我们就固定採用 8 bit = 1 byte 来储存一个 ASCII 字元,每个 ASCII 字元对应的二元码长度都是 8。

程式语言的 char 变数,记忆体大小正好就是 1 byte,用来储存一个 ASCII 字元。

8 bit = 1 byte,一共有 2^8 = 256 种数字,照理来说可以对应 256 种字元。不过 ASCII 只有 128 种字元,所以剩下的 128 种,就有人拿来自由运用。

写程式处理 ASCII

任何一本程式语言的书籍一定都有介绍,此处就不赘述了。

Big5

Code Page

ASCII 只有英文字,没有其他文字。世界各国为了让电脑处理自家文字,以及处理原本就有的英文(以便让电脑正常运作),于是世界各国皆以 ASCII 作为基础,各自创造自己的码以及编码解码方式,称作“内码表”。

世界各国也共同商议了内码表编号。例如编号 950 是繁体中文 Big5、编号 936 是简体中文 GB 2312、编号 932 是日文 Shift_JIS、编号 819 是西欧文字 ISO 8859-1、编号 37 是美加文字 EBCDIC US/Canada。

同样的码,套用不同的内码表,解码出来的文字就完全不同!想要处理其他国家的档案文件、网站页面、软体程式,就必须使用该国的内码表!例如浏览日本网站就得换日文内码表,阅读西欧文件就得换西欧文字内码表。

Big5

如果第一个 byte 是正数或零,那麽就确定是 ASCII 的字元。如果第一个 byte 是负数,就再读一个 byte,两个 byte 作为一个字元。

写程式处理 Big5

我尚未找到好读的资料,请读者各显神通。

我有找到一篇讲述 Big5 发展历史的文章:

http://libai.math.ncu.edu.tw/~shann/Chinese/big5.html

Big5 的瑕疵:他国无法执行软体

直到现今,大家还是习惯使用自家的内码表编写程式。

採用 Big5 制作软体,凡出现繁体中文字,在繁体中文作业系统会显示正确文字,在其他语言作业系统则会显示乱码。甚至当 Big5 与他国内码表的解码规则差太多时,解读长度不一致,读得太多太少,将造成程式指令大乱、程式当机。

相对地,世界上所有国家都有这样的问题。为了解决这个问题,微软设计了 AppLocale 软体,帮忙套用正确的内码表。日文电脑游戏玩家一定听过 AppLocale。

Big5 的瑕疵:无法同时显示多国文字

採用 Big5 制作文件,只能同时看到英文字和繁体中文字,无法看到其他文字。为了同时看到其他文字,热心人士推动了“Unicode 补完计划”,把简体中文字、日文字硬是补进 Big5 裡面。灵感来自于当时正在发展的 Unicode。

当时因为 Unicode 不流行,许多电脑系统尚不支援 Unicode,所以才出此奇招。现在 Unicode 已经普及,根本没有必要使用 Unicode 补完计划。

Big5 的瑕疵:许功盖问题

许、功、盖这三个字元(不只这三个),第二个 byte 刚好是\,刚好是 C 与 C++程式语言的“接续上一行”功能,也是众多程式语言的跳脱字元的开头(例如\n 与\t)。许功盖一旦出现在程式码当中,常常发生意想不到的结果。

Unicode

Unicode

替世界上的每一个文字暨符号,设定独一无二的编号。简单来说,就是把世上所有字符一一编号。

建立 Unicode 是一件浩大的工程,人类从二十几年前就开始动工,迄今已经接近完成,也相当普及了。详细的发展历程可以参考维基百科: http://zh.wikipedia.org/wiki/Unicode

编号大体上是这样安排:

前 128 个编号,与 ASCII 完全相同。
再来到前 65536 = 2byte 个编号,是世界各国常见文字。
再来到前 4294967296 = 4byte 个编号,是世界各国罕见文字。

编号通常使用十六进位表示法,开头加上 U+。

U+0041  <-> A
U+FF21  <-> A
U+FF1F  <-> ?
U+00E6  <-> æ
U+597D  <-> 好
U+3042  <-> あ
U+2260  <-> ≠
U+32A3  <-> ㊣
U+262F  <-> ☯
U+1F513 <-> 
                  
                  
                

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文