ASCII 中的控制字元

gaopengtttt發表於2016-11-24

Function/Control Code/Character in ASCII

Version: 2011-02-15

Author: green-waste (at) 163.com

【什麼是 Function Code 功能碼或  Function Character 功能字元】

ASCII 字符集,大家都知道吧,最基本的包含了 128 個字元。其中前 32 個, 0-31 ,即 0x00-0x1F ,都是不可見字元。這些字元,就叫做控制字元。

這些字元沒法列印出來,但是每個字元,都對應著一個特殊的控制功能的字元,簡稱功能字元或功能碼 Function Code 

簡言之: ASCII 中前 32 個字元,統稱為 Function Code 功能字元。

此外,由於 ASCII 中的 127 對應的是 Delete ,也是不可見的,所以,此處根據筆者的理解,也可以歸為 Function Code 

此類字元,對應不同的“功能”,起到一定的“控制作用”,所以,稱為控制字元。

關於每個控制字元的控制功能縮寫,參見下表:

 

表格     ASCII 中的控制字元


進位制

十六

進位制

控制

字元

轉義

字元 *

說明

Ctrl +

下列字母  *

0

00

NUL

/0

Null character( 空字元 )

@ (Shift + 2)

1

01

SOH

 

Start of Header( 標題開始 )

A

2

02

STX

 

Start of Text( 正文開始 )

B

3

03

ETX

 

End of Text( 正文結束 )

C

4

04

EOT

 

End of Transmission( 傳輸結束 )

D

5

05

ENQ

 

Enquiry( 請求 )

E

6

06

ACK

 

Acknowledgment( 收到通知 / 響應 )

F

7

07

BEL

/a

Bell ( 響鈴 )

G

8

08

BS

/b

Backspace( 退格 )

H

9

09

HT

/t

Horizontal Tab( 水平製表符 )

I

10

0A

LF

/n

Line feed( 換行鍵 )

J

11

0B

VT

/v

Vertical Tab( 垂直製表符 )

K

12

0C

FF

/f

Form feed( 換頁鍵 )

L

13

0D

CR

/r

Carriage return( Enter鍵 )

M

14

0E

SO

 

Shift Out( 不用切換 )

N

15

0F

SI

 

Shift In( 啟用切換 )

O

16

10

DLE

 

Data Link Escape( 資料鏈路轉義 )

P

17

11

DC1

 

Device Control 1( 裝置控制 1) /XON(Transmit On)

Q

18

12

DC2

 

Device Control 2( 裝置控制 2)

R

19

13

DC3

 

Device Control 3( 裝置控制 3) /XOFF(Transmit Off)

S

20

14

DC4

 

Device Control 4( 裝置控制 4)

T

21

15

NAK

 

Negative Acknowledgement( 拒絕接收 / 無響應 )

U

22

16

SYN

 

Synchronous Idle( 同步空閒 )

V

23

17

ETB

 

End of Trans the Block( 傳輸塊結束 )

W

24

18

CAN

 

Cancel( 取消 )

X

25

19

EM

 

End of Medium( 已到介質末端 / 介質儲存已滿 )

Y

26

1A

SUB

 

Substitute( 替補 / 替換 )

Z

27

1B

ESC

/e

Escape( 溢位 / 逃離 / 取消 )

[

28

1C

FS

 

File Separator( 檔案分割符 )

/

29

1D

GS

 

Group Separator( 分組符 )

]

30

1E

RS

 

Record Separator( 記錄分隔符 )

^ (Shit + 6)

31

1F

US

 

Unit Separator( 單元分隔符 )

_ (Shift + -)

32

20

SP

 

White space

[Space] *

127

7F

DEL

 

Delete( 刪除 )

[Delete] *




 (*) 

1.  跳脫字元:即在 C 語言中或其他地方如何表示。

2.  用鍵盤輸入控制字元:其中, 32 是空格鍵, 127  Delete 鍵,都不需要加 Ctrl 鍵,即可直接輸入。

3.  可以透過  “Ctrl+ 對應按鍵  實現上述控制字元的輸入  你可能遇到的一些,比如 :  Ctrl+V 輸入 SYNC  Ctrl+M 輸入Enter (當然也可以直接用 Enter 鍵,但是在 Windows 下面,其可能會傳送兩個字元: CR  LF ), Ctrl+Q 輸入 XON Ctrl+S 輸入 XOFF 等等。

 

 

其具體每個控制字元的含義,詳解介紹如下:

 ASCII 中的 Function/Control Code 功能字元的詳細含義】

 

0 – NUL – NUL l  字元 / 空字元

ASCII 字符集中的空字元, NULL ,起初本意可以看作為 NOP (中文意為空操作,就是啥都不做的意思),此位置可以忽略一個字元。

之所以有這個空字元,主要是用於計算機早期的記錄資訊的紙帶,此處留個 NUL 字元,意思是先佔這個位置,以待後用,比如你哪天想起來了,在這個位置在放一個別的啥字元之類的。

後來呢, NUL 字元被用於 C 語言中,字串的終結符,當一個字串中間出現 NUL / NULL ,程式碼裡面表現為 /0 ,的時候,就意味著這個是一個字串的結尾了。這樣就方便按照自己需求去定義字串,多長都行,當然只要你記憶體放得下,然後最後加一個 /0,  即空字元,意思是當前字串到此結束。

 

1 – SOH – S tart   O f H eading  標題開始

如果資訊溝通交流主要以命令和訊息的形式的話, SOH 就可以用於標記每個訊息的開始。

1963 年,最開始 ASCII 標準中,把此字元定義為 Start of Message ,後來又改為現在的 Start Of Heading 

現在,這個 SOH 常見於主從( master-slave )模式的 RS232 的通訊中,一個主裝置,以 SOH 開頭,和從裝置進行通訊。這樣方便從裝置在資料傳輸出現錯誤的時候,在下一次通訊之前,去實現重新同步( resynchronize )。如果沒有一個清晰的類似於 SOH 這樣的標記,去標記每個命令的起始或開頭的話,那麼重新同步,就很難實現了。

 

2 – STX – S tart O f T ext  文字開始

3 – ETX – E nd Of T ext  文字結束

透過某種通訊協議去傳輸的一個資料(包),稱為一幀的話,常會包含一個幀頭,包含了定址資訊,即你是要發給誰,要傳送到目的地是哪裡,其後跟著真正要傳送的資料內容。

 STX ,就用於標記這個資料內容的開始。接下來是要傳輸的資料,最後是 ETX ,表明資料的結束。

其中,中間具體傳輸的資料內容, ASCII 規範並沒有去定義,其和你所用的傳輸協議,具體自己要傳什麼資料有關。

 

幀頭

資料或文字內容

 

 

SOH(表明幀頭開始)

。。。。(幀頭資訊,比如包含了目的地址,表明你傳送給誰等等)

STX (表明資料開始)

。。。(真正要傳輸的資料)

ETX (表明資料結束)

         

 

 

不過其中有趣的是, 1963 年, ASCII 標準最初版本的時候,把現在的 STX 叫做 EOA  End Of Address ), ETX 叫做(End Of Message )。這是因為,最早的時候,一個訊息中,總是包含一個開始符和一個終止符。現在的新的定義,使得可以去傳送一個固定長度的命令,而只用一個 SOH 表明幀頭開始即可,而不需要再加上一個命令終止符或幀頭結束符。

 

總結一下:

一般傳送一個訊息,包含了一個幀頭和後面真正要傳的資料。

而對於幀頭,屬於控制類的資訊,這部分之前屬於命令,後面的真實要傳的資料屬於資料。即訊息 = 幀頭 + 資料。

而之前的命令都要有個開始符和結束符,這樣就是:

訊息        =  幀頭                                +  要傳的資料

 幀頭開始 + 幀頭資訊 + 幀頭結束         +  要傳的資料

而現在新的定義,使得只需要:

訊息        =  幀頭  + 要傳的資料

= SOH (表明幀頭開始) + 幀頭資訊     +  要傳的資料

= SOH (表明幀頭開始) + 幀頭資訊     + STX +  資料內容 +ETX

就可以少用一個幀頭結束符。

 

而如今,在很多協議中,也常見到,一個固定長度的幀頭,後面緊接著就是資料了,而沒有所謂的幀頭結束符之類的東西去區分幀頭和資料。

 

4 – EOT – E nd O f T ransmission  傳輸結束

5 – ENQ – ENQ uiry  請求

6 – ACK – ACK nowledgment  回應 / 響應

7 – BEL – [audible] BEL l

 

 ASCII 字符集中, BEL ,是個比較有意思的東東。因為其原先本意不是用來資料編碼的,於此相反, ASCII 中的其他字元,都是用於字元編碼(即用什麼字元,代表什麼含義)或者起到控制裝置的作用。 BEL 用一個可以聽得見的聲音,來吸引人們的注意,其原打算即用於計算機也用於一些裝置,比如印表機等。 C 語言裡面也支援此 BEL ,用 /a 來實現這個響鈴。

 

8 – BS – B ackS pace  退格鍵

退格鍵的功能,隨著時間變化,意義也變得不同了。

起初,意思是,在印表機和電傳打字機上,往回移動一格游標,以起到強調該字元的作用。比如你想要列印一個 a ,然後加上退格鍵後,就成了 aBS^ 。在機械類打字機上,此方法能夠起到實際的強調字元的作用,但是對於後來的 CTR 下時期來說,就無法起到對應效果了。

而現代所用的退格鍵,不僅僅表示游標往回移動了一格,同時也刪除了移動後該位置的字元。在 C 語言中,退格鍵可以用/b 表示。

 

9 – HT – H orizontal T ab  水平製表符

ASCII 中的 HT 控制符的作用是用於佈局的。

其控制輸出裝置前進到下一個表格去處理。而製表符 Table/Tab 的寬度也是靈活不固定的,只不過,多數裝置上,製表符Tab 的寬度都預定義為 8 。水平製表符 HT 不僅能減少資料輸入者的工作量,對於格式化好的文字來說,還能夠減少儲存空間,因為一個 Tab 鍵,就代替了 8 個空格,所以說省空間。

對於省空間的優點,我們現在來看,可能會覺得可笑,因為現在儲存空間已足夠大,一般來說根本不會需要去省那麼點可憐的儲存空間,但是實際上在計算機剛發明的時候,儲存空間(主要指的是記憶體)極其有限也極其昂貴,而且像 ZIP 等壓縮方法也還沒發明呢,所以對於當時來說,對於儲存空間,那是能夠省一點是一點,省任何一點,都是好的,也都是不容易的,省空間就是省錢啊。

C 語言中,用 /t 表示製表符。

 

10 – LF – L ine F eed  換行

LF ,直譯為(給印表機等)喂一行,意思就是所說的,換行。

換行字元,是 ASCII 字符集中,被誤用的字元中的其中一個。

LF 的最原始的含義是,移動印表機的頭到下一行。而另外一個 ASCII 字元, CR  Carriage Return )才是將印表機的頭,移到最左邊即一行的開始,行首。很多串列埠協議和 MS-DOS  Windows 作業系統,也都是這麼實現的。

而於此不同,對於 C 語言和 Unix 作業系統,其重新定義了 LF 字元的含義為新行,即 LF  CR 的組合才能表達出的,回車且換行的意思。

雖然你可以爭論哪種用法是錯的,但是,不可否認,是從程式的角度出發, C 語言和 Unix 對此 LF 的含義實現顯得就很自然,而 MS-DOS 的實現更接近於 LF 的本意。

如果最開始 ASCII 標準中,及定義  CF 也定義 newline ,那樣意思會清楚,會更好理理解:

LF 表示物理上的,裝置控制方面的移動到下一行(並沒有移動到行首);

新行( newline )表示邏輯上文字分隔符,即回車換行。

不過呢,現在人們常將 LF 用做 newline 新行的功能,而大多數文字編輯軟體也都可以處理單個 LF 或者 CR/LF 的組合了。

LF  C 語言中,用 /n 表示。

 

11 – VT – V ertical T ab  垂直製表符

垂直製表符,類似於水平製表符 Tab ,目的是為了減少佈局中的工作,同時也減少了格式化字元時所需要儲存字元的空間。 VT 控制碼用於跳到下一個標記行。說實話,還真沒看到有些地方需要用這個 VT 呢,因為一般在換行的時候,都是用 LF 代替 VT 了。

 

12 – FF – F orm F eed   換頁

設計換頁鍵,是用來控制印表機行為的。當印表機收到此鍵碼的時候,印表機移動到下一頁。不同的裝置的終端對此控制碼所表現的行為各不同。有些會去清除螢幕,而其他有的只是顯示 ^L 字元或者是隻是新換一行而已。 Shell 指令碼程式Bash  Tcsh 的實現方式是,把 FF 看作是一個清除螢幕的命令。 C 語言程式中用 /f 表示 FF (換頁)。

 

13 – CR – Carriage return  機器的滑動部分 / 底座   返回  ->  回車

CR 回車的原意是讓列印頭回到左邊界,並沒有移動到下一行。

隨著時間流逝,後來人把 CR 的意思弄成了 Enter 鍵,用於示意輸入完畢。在資料以螢幕顯示的情況下,人們在 Enter 的同時,也希望把游標移動到下一行。因此 C 語言和 Unix 作業系統,重新定義了 LF 的意思,使其表示為移動到下一行。當輸入 CR 去儲存資料的時候,軟體也常常隱式地將其轉換為 LF 

 

14 – SO – S hift O ut  不用切換

15 – SI – S hift I n   啟用切換

早在 1960s 年代,定義 ASCII 字符集的人,就已經懂得了,設計字符集不單單可以用於英文字符集,也要能應用於外文字符集,是很重要的。

定義 Shift In   Shift Out 的含義,即考慮到了此點。

最開始,其意為在西里爾語和拉丁語之間切換。西里爾 ASCII 定義中, KOI-7 用到了 Shift 字元。拉丁語用 Shift 去改變印表機的字型。在此種用途中, SO 用於產生雙倍寬度的字元,而用 SI 列印壓縮的字型。

 

16 – DLE – D ata L ink E scape  資料鏈路轉義

有時候,我們需要在正在進行的通訊過程中去傳送一些控制字元。但是,總有一些情況下,這些控制字元卻被看成了普通的資料流,而沒有起到對應的控制效果。而 ASCII 標準中,定義 DLE 來解決這類問題。

如果資料流中檢測到了 DLE ,資料接收端則對其後面接下來的資料流中的字元,另作處理。而關於具體如何處理這些字元, ASCII 規範中則沒有具體定義,而只是弄了個 DLE 去打斷正常資料的處理,告訴接下來的資料,要特殊對待。根據Modem 中的 Hayes 通訊協議 DLE 定義為“無聲 +++ 無聲”。以我的觀點,這樣可能會更好:如果 Hayes 協議沒有把DLE 處理為嵌入通訊的無聲狀態,那樣就符合現存的標準了。然而 Hayes 的開發者卻覺得 +++ 用的頻率要遠高於原始的DLE ,所以才這麼定義了。

 

17 – DC1 – D evice C ontrol 1 / XON – Transmission on

這個 ASCII 控制字元儘管原先定義為 DC1    但是現在常表示為 XON ,用於序列通訊中的軟體流控制。其主要作用為,在通訊被控制碼 XOFF 中斷之後,重新開始資訊傳輸。用過序列終端的人應該還記得,當有時候資料出錯了,按 Ctrl+Q(等價於 XON )有時候可以起到重新傳輸的效果。這是因為,此 Ctrl+Q 鍵盤序列實際上就是產生 XON 控制碼,其可以將那些由於終端或者主機方面,由於偶爾出現的錯誤的 XOFF 控制碼而中斷的通訊解鎖,使其正常通訊。

 

18 – DC2 – D evice C ontrol 2

19 – DC3 – D evice C ontrol 3 / XOFF – Transmission off  傳輸中斷

20 – DC4 – D evice C ontrol 4

21 – NAK – N egative A cK nowledgment  負面響應 ->  無響應  非正常響應

22 – SYN – SYN chronous idle

23 – ETB – E nd of T ransmission B lock  塊傳輸中止

24 – CAN – CAN cel  取消

25 – EM – E nd of M edium   已到介質末端,介質儲存已滿

EM 用於,當資料儲存到達序列儲存介質末尾的時候,就像磁帶或磁頭滾動到介質末尾一樣。其用於表述資料的邏輯終點,即不必非要是物理上的達到資料載體的末尾。

 

26 – SUB – SUB stitute character 替補 / 替換

27 – ESC – ESC ape  逃離 / 取消

字元 Escape ,是 ASCII 標準的首創的,由 Bob Bemer 提議的。用於開始一段控制碼的擴充套件字元。如此,即可以不必將所有可能想得到的字元都放到 ASCII 標準中了。因為,新的技術可能需要新的控制命令,而 ESC 可以用作這些字元命令的起始標誌。 ESC 廣泛用於印表機和終端,去控制裝置設定,比如字型,字元位置和顏色等等。如果最開始的 ASCII 標準中,沒有定義 ESC ,估計 ASCII 標準早就被其他標準所替代了,因為其沒有包含這些新出現的字元,所以肯定會有其他新的標準出現,用於表示這些字元的。即, ESC 給開發者提供了,可以根據需要而定義新含義的字元的可能。

 

28 – FS – F ile S eparator  檔案分隔符

檔案分隔符是個很有意思的控制字元,因為其可以讓我們看到 1960s 年代的時候,計算機技術是如何組織的。我們現在,習慣於隨即訪問一些儲存介質,比如 RAM ,磁碟,但是在定義 ASCII 標 準的那個年代,大部分資料還是順序的,序列的,而不是隨機訪問的。此處所說的序列的,不僅僅指的是序列通訊,還指的是順序儲存介質,比如穿孔卡片,紙帶, 磁帶等。在序列通訊的時代,設計這麼一個用於表示檔案分隔符的控制字元,用於分割兩個單獨的檔案,是一件很明智的事情。而 FS 的原因就在於此。

 

29 – GS – G roup S eparator 分組符

ASCII 定義控制字元的原因中,其中一條就是考慮到了資料儲存方面的情況。大部分情況下,資料庫的建立,都和表有關,包含了對應的記錄。同一個表中的所有的記錄,屬於同一型別。不同的表中的記錄,屬於對應的不同的型別。而分組符 GS 就是用來分隔序列資料儲存系統中的不同的組。值得注意的是,當時還沒有使用 word 的表格,當時 ASCII 時代的人,把他叫做組。

 

30 – RS – R ecord S eparator 記錄分隔符

記錄分隔符 RS 用於分隔在一個組或表內的多個記錄。

 

31 – US – U nit S eparator  單元分隔符

 ASCII 定義中,在資料庫中所儲存的,最小的資料項,叫做 Unit 單元。而現在我們稱其 field 域。單元分隔符 US 用於分割序列資料儲存環境下的不同的域。

現在大部分的資料庫實現,要求大部分型別都擁有固定的長度。

儘管大部分時候可能用不到,但是對於每一個域,卻都要分配足夠大的空間,用於存放最大可能的成員變數。這樣的做法,佔用了大量的儲存空間,而 US 控制碼允許域具有可變的長度。在 1960s 年代,資料儲存空間很有限,用 US 這個單元分隔符,將不同單元分隔開,這樣就可以實現更高效地儲存那些寶貴的資料。另一方面,序列儲存的儲存效率,遠低於RAM 和磁碟中所實現的表格儲存。我個人無法想象,如果現在的資料,還是儲存在自帶或者帶滾輪的磁帶上,會是何種景象。

 

32 – SP – White SP ace  空格鍵

也許你會爭論說,空格鍵是否真的能算是一個控制字元?因為現在在普通文字中使用空格鍵是如此常見。

但是,既然水平製表符和退格鍵在 ASCII 中, 都被叫做控制字元了,那麼我覺得也很自然地,可以把空格鍵(向前的空格)也叫做控制字元,畢竟,其本身並不代表一個真正的可見的字元,而僅僅只是很常用於 輸出裝置,用於處理位置前向移動一格,清除當前位置的內容而已。在很多程式中,比如字元處理程式,白空格同樣可能從導致行尾轉到下一行行首,而網路瀏覽器 將多個空格組合成單個空格輸出。

所以,這更加堅定了我的想法,覺得完全可以把空格看成是一個控制字元,而不僅僅是一個很獨特的普通字元。

 

127 – DEL – DEL ete   刪除

有人也許會問,為何 ASCII 字符集中的控制字元的值都是很小的,即 0-32 ,而 DEL 控制字元的值卻很大,是 127 。這是由於這個特殊的字元是為紙帶而定義的。而在那個時候,絕大多數的紙帶,都是用 7 個孔洞去編碼資料的。而 127 這個值所對應的二進位制值為 111 1111b ,表示所有 7 個位元位都是高,所以,將 DEL 用在現存的紙帶上時,所有的洞就都被穿孔了,就把已經存在的資料都擦出掉了,就起到了對應的刪除的作用了。

 

【引用】

1   

 

2    

 

3.  

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2129010/,如需轉載,請註明出處,否則將追究法律責任。

相關文章