目錄

名稱

perlebcdic - 在 EBCDIC 平台上執行 Perl 的考量

說明

探討 Perl 程式設計師在使用 EBCDIC 電腦時會遇到的部分問題。

此文件尚未完工的部分已標記為 XXX。

早期 Perl 版本可在部分 EBCDIC 電腦上執行,但已知最後一個可在 EBCDIC 上執行的版本為 v5.8.7,直到 v5.22,Perl 核心才又可在 z/OS 上執行。理論上,它可以在 OS/400 或 Siemens' BS2000(或其後繼版本)上執行,但這尚未經過測試。在 v5.22 和 5.24 中,並非所有在 CPAN 上找到但與核心 Perl 一起發布的模組都可以在 z/OS 上執行。

如果您想在非 z/OS EBCDIC 電腦上使用 Perl,請透過 https://github.com/Perl/perl5/issues 告知我們。

在 EBCDIC 平台上撰寫 Perl 程式與在 "ASCII" 平台上撰寫程式並無不同,但底層數字不同,我們稍後會說明。您必須了解這些 "ASCII" 平台,因為文件有偏見,而且經常會使用不適用於 EBCDIC 的範例數字。此外,很少有 CPAN 模組是專門為 EBCDIC 編寫且無法在 ASCII 上執行的;相反地,絕大多數 CPAN 模組都是為 ASCII 編寫,有些可能碰巧可以在 EBCDIC 上執行,而少數模組則設計為可以在兩者上執行。

如果您的程式碼僅使用 52 個字母 A-Z 和 a-z,加上空白鍵、數字 0-9,以及 Perl 使用的標點符號,加上一些由跳脫序列表示的控制字元,例如 \n\t,那麼使用 Perl 沒有什麼特別之處,而且您的程式碼很可能可以在 ASCII 電腦上執行,而不需要變更。

但是,如果您撰寫的程式碼使用 \005 表示 TAB 或 \xC1 表示 "A",或 \xDF 表示 "ÿ"(帶分音符的小寫 "y"),那麼您的程式碼很可能可以在您的 EBCDIC 平台上執行,但無法在 ASCII 平台上執行。如果沒有人會在 ASCII 平台上執行您的程式碼,這樣做是可以的;但本文檔的偏見在於撰寫可在 EBCDIC 和 ASCII 系統之間移植的程式碼。同樣地,如果您關心的每個字元都可以輕鬆從鍵盤輸入,您不需要了解任何 ASCII,但許多鍵盤無法讓您直接輸入字元,例如 \xDF,因此您必須間接指定它,例如使用 "\xDF" 跳脫序列。在這種情況下,最簡單的方法是了解一些 ASCII/Unicode 字元集。如果您知道小寫 "ÿ" 是 U+00FF,那麼您可以將其指定為 "\N{U+FF}",並讓電腦自動將其轉換為您平台上的 \xDF,並將其保留為 ASCII 平台上的 \xFF。或者,您可以透過名稱指定它,\N{LATIN SMALL LETTER Y WITH DIAERESIS,而不需要知道數字。這兩種方法都可以,但都需要熟悉 Unicode。

常見字元編碼集

ASCII

美國資訊交換標準碼(ASCII 或 US-ASCII)是一組從 0 到 127(十進位)的整數,這些整數由使用 ASCII 的電腦標準化詮釋。例如,65 表示字母「A」。範圍 0..127 可透過設定 7 位元二進制數字中的各種位元來涵蓋,因此該組有時稱為「7 位元 ASCII」。ASCII 由美國國家標準協會文件 ANSI X3.4-1986 描述。它也由 ISO 646:1991 描述(包含貨幣符號的在地化)。完整的 ASCII 組在 下方的表格中給出,為前 128 個元素。可以用 ASCII 中的字元充分書寫的語言包括英語、夏威夷語、印尼語、斯瓦希里語和一些美洲原住民語言。

大多數非 EBCDIC 字元集都是 ASCII 的超集。也就是說,整數 0-127 表示 ASCII 所說的意義。但整數 128 以上則特定於字元集。

其中許多完全符合 8 位元,使用 ASCII 作為 0-127,同時指定 128-255 的意義,且不使用 255 以上的任何內容。因此,這些是單位元組(或如果您喜歡,是八位元組)字元集。一個重要的字元集(因為 Unicode 是它的超集)是 ISO 8859-1 字元集。

ISO 8859

ISO 8859-$n 是國際標準化組織 (ISO) 的一組字元編碼集,每個字元編碼集都會將字元新增到 ASCII 組中,這些字元通常出現在各種語言中,其中許多基於羅馬字母或拉丁字母。大多數是歐洲語言,但也有阿拉伯語、希臘語、希伯來語和泰語。網路上有關於所有這些的良好參考。

拉丁文 1(ISO 8859-1)

ASCII 的特定 8 位元延伸,包括重音符和銳音符的拉丁字母。可以使用 ISO 8859-1 的語言包括 ASCII 涵蓋的所有語言,以及南非語、阿爾巴尼亞語、巴斯克語、加泰隆尼亞語、丹麥語、法羅語、芬蘭語、挪威語、葡萄牙語、西班牙語和瑞典語。荷蘭語涵蓋在內,但沒有 ij 連字。法語也涵蓋在內,但沒有 oe 連字。德語可以使用 ISO 8859-1,但必須在沒有德語式引號的情況下使用。此組基於 ASCII 的西歐延伸,且在萬維網工作中很常見。在 IBM 字元編碼集識別術語中,ISO 8859-1 也稱為 CCSID 819(或有時稱為 0819 甚至 00819)。

EBCDIC

延伸二進制編碼十進制交換碼是指一大組單位元組和多位元組編碼字元集,這些字元集與 ASCII 和 ISO 8859-1 非常不同,而且彼此之間都略有不同;它們通常在主機電腦上執行。EBCDIC 編碼源自霍勒斯穿孔卡編碼的 8 位元組延伸,這遠早於 ASCII。卡片上的配置使得高位元設定為大小寫字母字元 [a-z][A-Z],但在每個拉丁字母範圍內都有間隙,在 下方的表格中可見。這些間隙可能會造成複雜性。

有些 IBM EBCDIC 字元組可能已透過字元組識別碼編號 (CCSID 編號) 或程式碼頁編號而為人所知。

Perl 可在執行下列三種常見 EBCDIC 字元組的平台上編譯。

13 個變異字元

在 IBM EBCDIC 字元組識別碼編號中,有 13 個字元通常會對應到不同的整數值。這些字元稱為 13 個「變異」字元,而且是

\ [ ] { } ^ ~ ! # | $ @ `

當 Perl 為某個平台編譯時,它會查看所有這些字元以猜測該平台使用的 EBCDIC 字元組,並根據該平台適當地調整自己。如果該平台使用的字元組不是 Perl 所知的這三種字元組之一,Perl 將會無法編譯,或錯誤地且靜默地選擇這三種字元組之一。

換行符號 (LF) 字元實際上是第 14 個變異字元,而且 Perl 也會檢查它。

Perl 辨識的 EBCDIC 字元組

0037

字元組識別碼編號 0037 是 ASCII 加上拉丁文-1 字元 (即 ISO 8859-1) 對應到 EBCDIC 組的對應。0037 用於在執行於 AS/400 電腦上的 OS/400 作業系統上的北美英語地區設定。CCSID 0037 在 236 個地方與 ISO 8859-1 不同;換句話說,它們只在 20 個碼點值上相同。

1047

字元組識別碼編號 1047 也是 ASCII 加上拉丁文-1 字元 (即 ISO 8859-1) 對應到 EBCDIC 組的對應。1047 用於 OS/390 或 z/OS 的 Unix System Services,以及 VM/ESA 的 OpenEdition。CCSID 1047 在八個地方與 CCSID 0037 不同,而且在 236 個地方與 ISO 8859-1 不同。

POSIX-BC

在 Siemens' BS2000 系統上使用的 EBCDIC 程式碼頁與 1047 和 0037 不同。它在下方被識別為 POSIX-BC 組。與 0037 和 1047 一樣,它在 20 個碼點值上與 ISO 8859-1 相同。

Unicode 碼點與 EBCDIC 碼點

在 Unicode 術語中,碼點是指定給字元的數字:例如,在 EBCDIC 中,字元「A」通常指定數字 193。在 Unicode 中,字元「A」指定數字 65。ASCII 和拉丁文-1 (ISO 8859-1) 中的所有碼點在 Unicode 中具有相同的意義。所有三個已辨識的 EBCDIC 字元組都有 256 個碼點,而且在每個字元組中,所有 256 個碼點都對應到等效的 Latin1 碼點。顯然地,「A」會對應到「A」、「B」=>「B」、「%」=>「%」等,適用於 Latin1 和這些程式碼頁中的所有可列印字元。

事實證明,EBCDIC 幾乎有 ASCII/Latin1 C0 控制項和 DELETE 控制項的精確等效項。(C0 控制項是其 ASCII 碼點為 0..0x1F 的控制項;例如 TAB、ACK、BEL 等。)在這些 ASCII/EBCDIC 控制項之間設定了對應。在 ASCII 平台上的 C1 控制項和其餘的 EBCDIC 控制項之間沒有如此精確的對應。所作的動作是將這些控制項(大多數是任意地)對應到另一個字元組中其他未匹配的字元。大多數這些控制項現在在 EBCDIC 中很少使用,而且它們的名稱已在沒有太多抱怨的情況下被捨棄。例如,EO (八個一) EBCDIC 控制項(由八個一組成 = 0xFF)對應到 C1 APC 控制項 (0x9F),而且您無法使用名稱「EO」。

EBCDIC 控制項提供三個可能的行終止字元,CR (0x0D)、LF (0x25) 和 NL (0x15)。在 ASCII 平台上,「NL」和「LF」符號指的是同一個字元,但在嚴格的 EBCDIC 術語中,它們是不同的。EBCDIC NL 會對應到稱為「NEL」的 C1 控制項(「下一行」;這裡是對應很有道理的一個案例,因此並非只是隨意的)。在某些 EBCDIC 平台上,這個 NL 或 NEL 是典型的行終止字元。z/OS 和 BS2000 就是如此。在這些平台上,C 編譯器會交換 LF 和 NEL 程式碼點,因此 "\n" 是 0x15,並指涉 NL。Perl 也會這樣做;您可以在 下方的 程式碼圖表中看到。這會讓事情通常「正常運作」,而您甚至不需要知道有交換這件事。

Unicode 和 UTF

UTF 代表「Unicode 轉換格式」。UTF-8 是 Unicode 編碼成一連串 8 位元組塊的編碼,基於 ASCII 和 Latin-1。表示 Unicode 程式碼點所需的序列長度取決於該程式碼點的序號,數字越大需要的位元組越多。UTF-EBCDIC 類似於 UTF-8,但基於 EBCDIC。它們很類似,因此在一般用法中,這兩個術語會混為一談,並使用「UTF-8」來表示在 ASCII 平台上找到的 UTF-8,以及在 EBCDIC 平台上找到的 UTF-EBCDIC。

您可能會看到「不變」字元或程式碼點這個術語。這只表示當以 UTF-8(或 UTF-EBCDIC)編碼時,字元的數字值和表示法與未編碼時相同。(請注意,這與上面提到的 「13 個變異字元」 是非常不同的概念。謹慎的文字會使用「UTF-8 不變」這個術語,而不是只用「不變」,但您最常只會看到「不變」。)例如,「A」的序號在大部分 EBCDIC 編碼頁中為 193,在以 UTF-EBCDIC 編碼時也是 193。所有 UTF-8(或 UTF-EBCDIC)變異程式碼點在以 UTF-8(或 UTF-EBCDIC)編碼時,會佔用至少兩個位元組;根據定義,UTF-8(或 UTF-EBCDIC)不變程式碼點在以 UTF-8(或 UTF-EBCDIC)編碼時,或未編碼時,只會佔用一個位元組。(現在您知道為什麼人們通常只在說「UTF-8」時,也表示「UTF-EBCDIC」。在本文檔的其餘部分,我們大多也會這樣隨意。)在 ASCII UTF-8 中,對應於最低 128 個序號(0 - 127:ASCII 字元)的程式碼點是不變的。在 UTF-EBCDIC 中,有 160 個不變字元。(如果您想知道,EBCDIC 不變字元是那些有 ASCII 等效字元的字元,加上那些對應於 C1 控制項的字元(在 ASCII 平台上為 128 - 159)。)

以 UTF-EBCDIC 編碼的字串可能會比以 UTF-8 編碼的字串長(極少情況下會較短)。Perl 延伸了 UTF-8 和 UTF-EBCDIC,以便它們可以編碼高於 Unicode 最大值 U+10FFFF 的碼點。這兩個延伸都是建構來允許編碼任何符合 64 位元組字元的碼點。

UTF-EBCDIC 是由 Unicode 技術報告 #16(通常簡稱為 TR16)定義的。它是根據 CCSID 1047 定義的,不允許其他程式碼頁的差異。這允許在執行不同程式碼頁的電腦之間輕鬆交換文字,但對於在這些其他程式碼頁上執行 Perl,則無法使用,除非進行調整。

無法使用的理由是 Perl 的一個基本假設是,它在分析和詞彙分析時所關心的字元,無論文字是否以 UTF-8 編碼,都是相同的。例如,Perl 預期字元 "[" 具有相同的表示方式,無論包含它的字串(或程式碼文字)是否以 UTF-8 編碼。為了確保這一點,Perl 會將 UTF-EBCDIC 調整到特定的程式碼頁,以便它預期為 UTF-8 不變的所有字元實際上都是 UTF-8 不變的。這表示在執行 Perl 的 UTF-EBCDIC 其中一個版本的電腦上產生的文字,必須轉換才能讓執行另一個版本的電腦理解。

TR16 暗示了一種方法,可以將 UTF-EBCDIC 延伸到編碼高達 2 ** 31 - 1 的點。Perl 對高達 2 ** 30 - 1 的碼點使用此方法,但對較大的碼點使用不相容的方法,以使其能夠處理比其他方法大得多的碼點。

使用編碼

從 Perl 5.8 開始,您可以使用標準模組編碼從 EBCDIC 轉換為 Latin-1 碼點。編碼知道比 Perl 目前可以編譯執行的更多的 EBCDIC 字元集。

use Encode 'from_to';

my %ebcdic = ( 176 => 'cp37', 95 => 'cp1047', 106 => 'posix-bc' );

# $a is in EBCDIC code points
from_to($a, $ebcdic{ord '^'}, 'latin1');
# $a is ISO 8859-1 code points

並從 Latin-1 碼點轉換為 EBCDIC 碼點

use Encode 'from_to';

my %ebcdic = ( 176 => 'cp37', 95 => 'cp1047', 106 => 'posix-bc' );

# $a is ISO 8859-1 code points
from_to($a, 'latin1', $ebcdic{ord '^'});
# $a is in EBCDIC code points

建議您使用 PerlIO 的自動轉換功能來執行 I/O,請參閱 perluniintro

自版本 5.8 以來,Perl 使用 PerlIO I/O 函式庫。這使您可以對每個 IO 通道使用不同的編碼。例如,您可以使用

use Encode;
open($f, ">:encoding(ascii)", "test.ascii");
print $f "Hello World!\n";
open($f, ">:encoding(cp37)", "test.ebcdic");
print $f "Hello World!\n";
open($f, ">:encoding(latin1)", "test.latin1");
print $f "Hello World!\n";
open($f, ">:encoding(utf8)", "test.utf8");
print $f "Hello World!\n";

取得四個包含「Hello World!\n」的檔案,分別以 ASCII、CP 0037 EBCDIC、ISO 8859-1(Latin-1)(在此範例中與 ASCII 相同,因為只印出 ASCII 字元)和 UTF-EBCDIC(在此範例中與一般 EBCDIC 相同,因為只印出 EBCDIC 和 UTF-EBCDIC 之間沒有差異的字元)。有關詳細資訊,請參閱 Encode::PerlIO 的文件。

由於 PerlIO 層在內部使用原始 IO(位元組),因此這完全忽略了檔案系統類型(ASCII 或 EBCDIC)等事項。

單八位元組表格

下列表格列出 ASCII 和 Latin 1 排序的集合,包括子集合:C0 控制碼 (0..31)、ASCII 繪圖字元 (32..7e)、刪除 (7f)、C1 控制碼 (80..9f) 和 Latin-1 (又稱 ISO 8859-1) (a0..ff)。在表格名稱中,ASCII 的 Latin 1 延伸字元已標示為字元名稱,大致對應於《Unicode 標準,第 6.1 版》,儘管在所有情況下都以替換為準,例如 s/LATIN//s/VULGAR//;在某些情況下為 s/CAPITAL LETTER//;在某些其他情況下為 s/SMALL LETTER ([A-Z])/\l$1/。控制碼使用 Unicode 6.2 縮寫列出。0037 和 1047 集合之間的差異標示為 **。1047 和 POSIX-BC 集合之間的差異標示為 ##. 所有列出的 ord() 數字均為十進位。如果您想查看此表格列出的八進位值,請執行表格(也就是此文件的 pod 原始文字,因為此食譜可能無法與 pod2_other_format 翻譯搭配使用)

食譜 0
perl -ne 'if(/(.{29})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/)' \
 -e '{printf("%s%-5.03o%-5.03o%-5.03o%.03o\n",$1,$2,$3,$4,$5)}' \
 perlebcdic.pod

如果您想保留 UTF-x 碼點,則在指令碼形式中,您可能想寫

食譜 1
open(FH,"<perlebcdic.pod") or die "Could not open perlebcdic.pod: $!";
while (<FH>) {
    if (/(.{29})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\.?(\d*)
                                                    \s+(\d+)\.?(\d*)/x)
    {
        if ($7 ne '' && $9 ne '') {
            printf(
               "%s%-5.03o%-5.03o%-5.03o%-5.03o%-3o.%-5o%-3o.%.03o\n",
                                           $1,$2,$3,$4,$5,$6,$7,$8,$9);
        }
        elsif ($7 ne '') {
            printf("%s%-5.03o%-5.03o%-5.03o%-5.03o%-3o.%-5o%.03o\n",
                                          $1,$2,$3,$4,$5,$6,$7,$8);
        }
        else {
            printf("%s%-5.03o%-5.03o%-5.03o%-5.03o%-5.03o%.03o\n",
                                               $1,$2,$3,$4,$5,$6,$8);
        }
    }
}

如果您想查看此表格列出的十六進位值,請執行表格

食譜 2
perl -ne 'if(/(.{29})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/)' \
 -e '{printf("%s%-5.02X%-5.02X%-5.02X%.02X\n",$1,$2,$3,$4,$5)}' \
 perlebcdic.pod

或者,為了保留十六進位的 UTF-x 碼點

食譜 3
open(FH,"<perlebcdic.pod") or die "Could not open perlebcdic.pod: $!";
while (<FH>) {
    if (/(.{29})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\.?(\d*)
                                                    \s+(\d+)\.?(\d*)/x)
    {
        if ($7 ne '' && $9 ne '') {
            printf(
               "%s%-5.02X%-5.02X%-5.02X%-5.02X%-2X.%-6.02X%02X.%02X\n",
                                          $1,$2,$3,$4,$5,$6,$7,$8,$9);
        }
        elsif ($7 ne '') {
            printf("%s%-5.02X%-5.02X%-5.02X%-5.02X%-2X.%-6.02X%02X\n",
                                             $1,$2,$3,$4,$5,$6,$7,$8);
        }
        else {
            printf("%s%-5.02X%-5.02X%-5.02X%-5.02X%-5.02X%02X\n",
                                                 $1,$2,$3,$4,$5,$6,$8);
        }
    }
}


                         ISO
                        8859-1             POS-         CCSID
                        CCSID  CCSID CCSID IX-          1047
 chr                     0819   0037 1047  BC  UTF-8  UTF-EBCDIC
---------------------------------------------------------------------
<NUL>                       0    0    0    0    0        0
<SOH>                       1    1    1    1    1        1
<STX>                       2    2    2    2    2        2
<ETX>                       3    3    3    3    3        3
<EOT>                       4    55   55   55   4        55
<ENQ>                       5    45   45   45   5        45
<ACK>                       6    46   46   46   6        46
<BEL>                       7    47   47   47   7        47
<BS>                        8    22   22   22   8        22
<HT>                        9    5    5    5    9        5
<LF>                        10   37   21   21   10       21  **
<VT>                        11   11   11   11   11       11
<FF>                        12   12   12   12   12       12
<CR>                        13   13   13   13   13       13
<SO>                        14   14   14   14   14       14
<SI>                        15   15   15   15   15       15
<DLE>                       16   16   16   16   16       16
<DC1>                       17   17   17   17   17       17
<DC2>                       18   18   18   18   18       18
<DC3>                       19   19   19   19   19       19
<DC4>                       20   60   60   60   20       60
<NAK>                       21   61   61   61   21       61
<SYN>                       22   50   50   50   22       50
<ETB>                       23   38   38   38   23       38
<CAN>                       24   24   24   24   24       24
<EOM>                       25   25   25   25   25       25
<SUB>                       26   63   63   63   26       63
<ESC>                       27   39   39   39   27       39
<FS>                        28   28   28   28   28       28
<GS>                        29   29   29   29   29       29
<RS>                        30   30   30   30   30       30
<US>                        31   31   31   31   31       31
<SPACE>                     32   64   64   64   32       64
!                           33   90   90   90   33       90
"                           34   127  127  127  34       127
#                           35   123  123  123  35       123
$                           36   91   91   91   36       91
%                           37   108  108  108  37       108
&                           38   80   80   80   38       80
'                           39   125  125  125  39       125
(                           40   77   77   77   40       77
)                           41   93   93   93   41       93
*                           42   92   92   92   42       92
+                           43   78   78   78   43       78
,                           44   107  107  107  44       107
-                           45   96   96   96   45       96
.                           46   75   75   75   46       75
/                           47   97   97   97   47       97
0                           48   240  240  240  48       240
1                           49   241  241  241  49       241
2                           50   242  242  242  50       242
3                           51   243  243  243  51       243
4                           52   244  244  244  52       244
5                           53   245  245  245  53       245
6                           54   246  246  246  54       246
7                           55   247  247  247  55       247
8                           56   248  248  248  56       248
9                           57   249  249  249  57       249
:                           58   122  122  122  58       122
;                           59   94   94   94   59       94
<                           60   76   76   76   60       76
=                           61   126  126  126  61       126
>                           62   110  110  110  62       110
?                           63   111  111  111  63       111
@                           64   124  124  124  64       124
A                           65   193  193  193  65       193
B                           66   194  194  194  66       194
C                           67   195  195  195  67       195
D                           68   196  196  196  68       196
E                           69   197  197  197  69       197
F                           70   198  198  198  70       198
G                           71   199  199  199  71       199
H                           72   200  200  200  72       200
I                           73   201  201  201  73       201
J                           74   209  209  209  74       209
K                           75   210  210  210  75       210
L                           76   211  211  211  76       211
M                           77   212  212  212  77       212
N                           78   213  213  213  78       213
O                           79   214  214  214  79       214
P                           80   215  215  215  80       215
Q                           81   216  216  216  81       216
R                           82   217  217  217  82       217
S                           83   226  226  226  83       226
T                           84   227  227  227  84       227
U                           85   228  228  228  85       228
V                           86   229  229  229  86       229
W                           87   230  230  230  87       230
X                           88   231  231  231  88       231
Y                           89   232  232  232  89       232
Z                           90   233  233  233  90       233
[                           91   186  173  187  91       173  ** ##
\                           92   224  224  188  92       224  ##
]                           93   187  189  189  93       189  **
^                           94   176  95   106  94       95   ** ##
_                           95   109  109  109  95       109
`                           96   121  121  74   96       121  ##
a                           97   129  129  129  97       129
b                           98   130  130  130  98       130
c                           99   131  131  131  99       131
d                           100  132  132  132  100      132
e                           101  133  133  133  101      133
f                           102  134  134  134  102      134
g                           103  135  135  135  103      135
h                           104  136  136  136  104      136
i                           105  137  137  137  105      137
j                           106  145  145  145  106      145
k                           107  146  146  146  107      146
l                           108  147  147  147  108      147
m                           109  148  148  148  109      148
n                           110  149  149  149  110      149
o                           111  150  150  150  111      150
p                           112  151  151  151  112      151
q                           113  152  152  152  113      152
r                           114  153  153  153  114      153
s                           115  162  162  162  115      162
t                           116  163  163  163  116      163
u                           117  164  164  164  117      164
v                           118  165  165  165  118      165
w                           119  166  166  166  119      166
x                           120  167  167  167  120      167
y                           121  168  168  168  121      168
z                           122  169  169  169  122      169
{                           123  192  192  251  123      192  ##
|                           124  79   79   79   124      79
}                           125  208  208  253  125      208  ##
~                           126  161  161  255  126      161  ##
<DEL>                       127  7    7    7    127      7
<PAD>                       128  32   32   32   194.128  32
<HOP>                       129  33   33   33   194.129  33
<BPH>                       130  34   34   34   194.130  34
<NBH>                       131  35   35   35   194.131  35
<IND>                       132  36   36   36   194.132  36
<NEL>                       133  21   37   37   194.133  37   **
<SSA>                       134  6    6    6    194.134  6
<ESA>                       135  23   23   23   194.135  23
<HTS>                       136  40   40   40   194.136  40
<HTJ>                       137  41   41   41   194.137  41
<VTS>                       138  42   42   42   194.138  42
<PLD>                       139  43   43   43   194.139  43
<PLU>                       140  44   44   44   194.140  44
<RI>                        141  9    9    9    194.141  9
<SS2>                       142  10   10   10   194.142  10
<SS3>                       143  27   27   27   194.143  27
<DCS>                       144  48   48   48   194.144  48
<PU1>                       145  49   49   49   194.145  49
<PU2>                       146  26   26   26   194.146  26
<STS>                       147  51   51   51   194.147  51
<CCH>                       148  52   52   52   194.148  52
<MW>                        149  53   53   53   194.149  53
<SPA>                       150  54   54   54   194.150  54
<EPA>                       151  8    8    8    194.151  8
<SOS>                       152  56   56   56   194.152  56
<SGC>                       153  57   57   57   194.153  57
<SCI>                       154  58   58   58   194.154  58
<CSI>                       155  59   59   59   194.155  59
<ST>                        156  4    4    4    194.156  4
<OSC>                       157  20   20   20   194.157  20
<PM>                        158  62   62   62   194.158  62
<APC>                       159  255  255  95   194.159  255      ##
<NON-BREAKING SPACE>        160  65   65   65   194.160  128.65
<INVERTED "!" >             161  170  170  170  194.161  128.66
<CENT SIGN>                 162  74   74   176  194.162  128.67   ##
<POUND SIGN>                163  177  177  177  194.163  128.68
<CURRENCY SIGN>             164  159  159  159  194.164  128.69
<YEN SIGN>                  165  178  178  178  194.165  128.70
<BROKEN BAR>                166  106  106  208  194.166  128.71   ##
<SECTION SIGN>              167  181  181  181  194.167  128.72
<DIAERESIS>                 168  189  187  121  194.168  128.73   ** ##
<COPYRIGHT SIGN>            169  180  180  180  194.169  128.74
<FEMININE ORDINAL>          170  154  154  154  194.170  128.81
<LEFT POINTING GUILLEMET>   171  138  138  138  194.171  128.82
<NOT SIGN>                  172  95   176  186  194.172  128.83   ** ##
<SOFT HYPHEN>               173  202  202  202  194.173  128.84
<REGISTERED TRADE MARK>     174  175  175  175  194.174  128.85
<MACRON>                    175  188  188  161  194.175  128.86   ##
<DEGREE SIGN>               176  144  144  144  194.176  128.87
<PLUS-OR-MINUS SIGN>        177  143  143  143  194.177  128.88
<SUPERSCRIPT TWO>           178  234  234  234  194.178  128.89
<SUPERSCRIPT THREE>         179  250  250  250  194.179  128.98
<ACUTE ACCENT>              180  190  190  190  194.180  128.99
<MICRO SIGN>                181  160  160  160  194.181  128.100
<PARAGRAPH SIGN>            182  182  182  182  194.182  128.101
<MIDDLE DOT>                183  179  179  179  194.183  128.102
<CEDILLA>                   184  157  157  157  194.184  128.103
<SUPERSCRIPT ONE>           185  218  218  218  194.185  128.104
<MASC. ORDINAL INDICATOR>   186  155  155  155  194.186  128.105
<RIGHT POINTING GUILLEMET>  187  139  139  139  194.187  128.106
<FRACTION ONE QUARTER>      188  183  183  183  194.188  128.112
<FRACTION ONE HALF>         189  184  184  184  194.189  128.113
<FRACTION THREE QUARTERS>   190  185  185  185  194.190  128.114
<INVERTED QUESTION MARK>    191  171  171  171  194.191  128.115
<A WITH GRAVE>              192  100  100  100  195.128  138.65
<A WITH ACUTE>              193  101  101  101  195.129  138.66
<A WITH CIRCUMFLEX>         194  98   98   98   195.130  138.67
<A WITH TILDE>              195  102  102  102  195.131  138.68
<A WITH DIAERESIS>          196  99   99   99   195.132  138.69
<A WITH RING ABOVE>         197  103  103  103  195.133  138.70
<CAPITAL LIGATURE AE>       198  158  158  158  195.134  138.71
<C WITH CEDILLA>            199  104  104  104  195.135  138.72
<E WITH GRAVE>              200  116  116  116  195.136  138.73
<E WITH ACUTE>              201  113  113  113  195.137  138.74
<E WITH CIRCUMFLEX>         202  114  114  114  195.138  138.81
<E WITH DIAERESIS>          203  115  115  115  195.139  138.82
<I WITH GRAVE>              204  120  120  120  195.140  138.83
<I WITH ACUTE>              205  117  117  117  195.141  138.84
<I WITH CIRCUMFLEX>         206  118  118  118  195.142  138.85
<I WITH DIAERESIS>          207  119  119  119  195.143  138.86
<CAPITAL LETTER ETH>        208  172  172  172  195.144  138.87
<N WITH TILDE>              209  105  105  105  195.145  138.88
<O WITH GRAVE>              210  237  237  237  195.146  138.89
<O WITH ACUTE>              211  238  238  238  195.147  138.98
<O WITH CIRCUMFLEX>         212  235  235  235  195.148  138.99
<O WITH TILDE>              213  239  239  239  195.149  138.100
<O WITH DIAERESIS>          214  236  236  236  195.150  138.101
<MULTIPLICATION SIGN>       215  191  191  191  195.151  138.102
<O WITH STROKE>             216  128  128  128  195.152  138.103
<U WITH GRAVE>              217  253  253  224  195.153  138.104  ##
<U WITH ACUTE>              218  254  254  254  195.154  138.105
<U WITH CIRCUMFLEX>         219  251  251  221  195.155  138.106  ##
<U WITH DIAERESIS>          220  252  252  252  195.156  138.112
<Y WITH ACUTE>              221  173  186  173  195.157  138.113  ** ##
<CAPITAL LETTER THORN>      222  174  174  174  195.158  138.114
<SMALL LETTER SHARP S>      223  89   89   89   195.159  138.115
<a WITH GRAVE>              224  68   68   68   195.160  139.65
<a WITH ACUTE>              225  69   69   69   195.161  139.66
<a WITH CIRCUMFLEX>         226  66   66   66   195.162  139.67
<a WITH TILDE>              227  70   70   70   195.163  139.68
<a WITH DIAERESIS>          228  67   67   67   195.164  139.69
<a WITH RING ABOVE>         229  71   71   71   195.165  139.70
<SMALL LIGATURE ae>         230  156  156  156  195.166  139.71
<c WITH CEDILLA>            231  72   72   72   195.167  139.72
<e WITH GRAVE>              232  84   84   84   195.168  139.73
<e WITH ACUTE>              233  81   81   81   195.169  139.74
<e WITH CIRCUMFLEX>         234  82   82   82   195.170  139.81
<e WITH DIAERESIS>          235  83   83   83   195.171  139.82
<i WITH GRAVE>              236  88   88   88   195.172  139.83
<i WITH ACUTE>              237  85   85   85   195.173  139.84
<i WITH CIRCUMFLEX>         238  86   86   86   195.174  139.85
<i WITH DIAERESIS>          239  87   87   87   195.175  139.86
<SMALL LETTER eth>          240  140  140  140  195.176  139.87
<n WITH TILDE>              241  73   73   73   195.177  139.88
<o WITH GRAVE>              242  205  205  205  195.178  139.89
<o WITH ACUTE>              243  206  206  206  195.179  139.98
<o WITH CIRCUMFLEX>         244  203  203  203  195.180  139.99
<o WITH TILDE>              245  207  207  207  195.181  139.100
<o WITH DIAERESIS>          246  204  204  204  195.182  139.101
<DIVISION SIGN>             247  225  225  225  195.183  139.102
<o WITH STROKE>             248  112  112  112  195.184  139.103
<u WITH GRAVE>              249  221  221  192  195.185  139.104  ##
<u WITH ACUTE>              250  222  222  222  195.186  139.105
<u WITH CIRCUMFLEX>         251  219  219  219  195.187  139.106
<u WITH DIAERESIS>          252  220  220  220  195.188  139.112
<y WITH ACUTE>              253  141  141  141  195.189  139.113
<SMALL LETTER thorn>        254  142  142  142  195.190  139.114
<y WITH DIAERESIS>          255  223  223  223  195.191  139.115

如果您想查看上述表格以 CCSID 0037 順序顯示,而不是 ASCII + Latin-1 順序,請執行表格

食譜 4
perl \
   -ne 'if(/.{29}\d{1,3}\s{2,4}\d{1,3}\s{2,4}\d{1,3}\s{2,4}\d{1,3}/)'\
    -e '{push(@l,$_)}' \
    -e 'END{print map{$_->[0]}' \
    -e '          sort{$a->[1] <=> $b->[1]}' \
    -e '          map{[$_,substr($_,34,3)]}@l;}' perlebcdic.pod

如果您想以 CCSID 1047 順序查看,請將最後一行的數字 34 變更為 39,如下所示

食譜 5
perl \
   -ne 'if(/.{29}\d{1,3}\s{2,4}\d{1,3}\s{2,4}\d{1,3}\s{2,4}\d{1,3}/)'\
   -e '{push(@l,$_)}' \
   -e 'END{print map{$_->[0]}' \
   -e '          sort{$a->[1] <=> $b->[1]}' \
   -e '          map{[$_,substr($_,39,3)]}@l;}' perlebcdic.pod

如果您想以 POSIX-BC 順序查看,請將最後一行的數字 34 變更為 44,如下所示

食譜 6
perl \
   -ne 'if(/.{29}\d{1,3}\s{2,4}\d{1,3}\s{2,4}\d{1,3}\s{2,4}\d{1,3}/)'\
    -e '{push(@l,$_)}' \
    -e 'END{print map{$_->[0]}' \
    -e '          sort{$a->[1] <=> $b->[1]}' \
    -e '          map{[$_,substr($_,44,3)]}@l;}' perlebcdic.pod

十六進位表格,以 1047 順序排序

自此文件首次撰寫以來,慣例已越來越傾向於使用十六進位表示法表示碼點。要使用食譜執行此操作並進行排序是一個多步驟的程序,因此,為了方便起見,以下是上述表格,已重新排序為使用十六進位表示法,並以 1047 代碼頁順序顯示。

                         ISO
                        8859-1             POS-         CCSID
                        CCSID  CCSID CCSID IX-          1047
 chr                     0819   0037 1047  BC  UTF-8  UTF-EBCDIC
---------------------------------------------------------------------
<NUL>                       00   00   00   00   00       00
<SOH>                       01   01   01   01   01       01
<STX>                       02   02   02   02   02       02
<ETX>                       03   03   03   03   03       03
<ST>                        9C   04   04   04   C2.9C    04
<HT>                        09   05   05   05   09       05
<SSA>                       86   06   06   06   C2.86    06
<DEL>                       7F   07   07   07   7F       07
<EPA>                       97   08   08   08   C2.97    08
<RI>                        8D   09   09   09   C2.8D    09
<SS2>                       8E   0A   0A   0A   C2.8E    0A
<VT>                        0B   0B   0B   0B   0B       0B
<FF>                        0C   0C   0C   0C   0C       0C
<CR>                        0D   0D   0D   0D   0D       0D
<SO>                        0E   0E   0E   0E   0E       0E
<SI>                        0F   0F   0F   0F   0F       0F
<DLE>                       10   10   10   10   10       10
<DC1>                       11   11   11   11   11       11
<DC2>                       12   12   12   12   12       12
<DC3>                       13   13   13   13   13       13
<OSC>                       9D   14   14   14   C2.9D    14
<LF>                        0A   25   15   15   0A       15    **
<BS>                        08   16   16   16   08       16
<ESA>                       87   17   17   17   C2.87    17
<CAN>                       18   18   18   18   18       18
<EOM>                       19   19   19   19   19       19
<PU2>                       92   1A   1A   1A   C2.92    1A
<SS3>                       8F   1B   1B   1B   C2.8F    1B
<FS>                        1C   1C   1C   1C   1C       1C
<GS>                        1D   1D   1D   1D   1D       1D
<RS>                        1E   1E   1E   1E   1E       1E
<US>                        1F   1F   1F   1F   1F       1F
<PAD>                       80   20   20   20   C2.80    20
<HOP>                       81   21   21   21   C2.81    21
<BPH>                       82   22   22   22   C2.82    22
<NBH>                       83   23   23   23   C2.83    23
<IND>                       84   24   24   24   C2.84    24
<NEL>                       85   15   25   25   C2.85    25     **
<ETB>                       17   26   26   26   17       26
<ESC>                       1B   27   27   27   1B       27
<HTS>                       88   28   28   28   C2.88    28
<HTJ>                       89   29   29   29   C2.89    29
<VTS>                       8A   2A   2A   2A   C2.8A    2A
<PLD>                       8B   2B   2B   2B   C2.8B    2B
<PLU>                       8C   2C   2C   2C   C2.8C    2C
<ENQ>                       05   2D   2D   2D   05       2D
<ACK>                       06   2E   2E   2E   06       2E
<BEL>                       07   2F   2F   2F   07       2F
<DCS>                       90   30   30   30   C2.90    30
<PU1>                       91   31   31   31   C2.91    31
<SYN>                       16   32   32   32   16       32
<STS>                       93   33   33   33   C2.93    33
<CCH>                       94   34   34   34   C2.94    34
<MW>                        95   35   35   35   C2.95    35
<SPA>                       96   36   36   36   C2.96    36
<EOT>                       04   37   37   37   04       37
<SOS>                       98   38   38   38   C2.98    38
<SGC>                       99   39   39   39   C2.99    39
<SCI>                       9A   3A   3A   3A   C2.9A    3A
<CSI>                       9B   3B   3B   3B   C2.9B    3B
<DC4>                       14   3C   3C   3C   14       3C
<NAK>                       15   3D   3D   3D   15       3D
<PM>                        9E   3E   3E   3E   C2.9E    3E
<SUB>                       1A   3F   3F   3F   1A       3F
<SPACE>                     20   40   40   40   20       40
<NON-BREAKING SPACE>        A0   41   41   41   C2.A0    80.41
<a WITH CIRCUMFLEX>         E2   42   42   42   C3.A2    8B.43
<a WITH DIAERESIS>          E4   43   43   43   C3.A4    8B.45
<a WITH GRAVE>              E0   44   44   44   C3.A0    8B.41
<a WITH ACUTE>              E1   45   45   45   C3.A1    8B.42
<a WITH TILDE>              E3   46   46   46   C3.A3    8B.44
<a WITH RING ABOVE>         E5   47   47   47   C3.A5    8B.46
<c WITH CEDILLA>            E7   48   48   48   C3.A7    8B.48
<n WITH TILDE>              F1   49   49   49   C3.B1    8B.58
<CENT SIGN>                 A2   4A   4A   B0   C2.A2    80.43  ##
.                           2E   4B   4B   4B   2E       4B
<                           3C   4C   4C   4C   3C       4C
(                           28   4D   4D   4D   28       4D
+                           2B   4E   4E   4E   2B       4E
|                           7C   4F   4F   4F   7C       4F
&                           26   50   50   50   26       50
<e WITH ACUTE>              E9   51   51   51   C3.A9    8B.4A
<e WITH CIRCUMFLEX>         EA   52   52   52   C3.AA    8B.51
<e WITH DIAERESIS>          EB   53   53   53   C3.AB    8B.52
<e WITH GRAVE>              E8   54   54   54   C3.A8    8B.49
<i WITH ACUTE>              ED   55   55   55   C3.AD    8B.54
<i WITH CIRCUMFLEX>         EE   56   56   56   C3.AE    8B.55
<i WITH DIAERESIS>          EF   57   57   57   C3.AF    8B.56
<i WITH GRAVE>              EC   58   58   58   C3.AC    8B.53
<SMALL LETTER SHARP S>      DF   59   59   59   C3.9F    8A.73
!                           21   5A   5A   5A   21       5A
$                           24   5B   5B   5B   24       5B
*                           2A   5C   5C   5C   2A       5C
)                           29   5D   5D   5D   29       5D
;                           3B   5E   5E   5E   3B       5E
^                           5E   B0   5F   6A   5E       5F     ** ##
-                           2D   60   60   60   2D       60
/                           2F   61   61   61   2F       61
<A WITH CIRCUMFLEX>         C2   62   62   62   C3.82    8A.43
<A WITH DIAERESIS>          C4   63   63   63   C3.84    8A.45
<A WITH GRAVE>              C0   64   64   64   C3.80    8A.41
<A WITH ACUTE>              C1   65   65   65   C3.81    8A.42
<A WITH TILDE>              C3   66   66   66   C3.83    8A.44
<A WITH RING ABOVE>         C5   67   67   67   C3.85    8A.46
<C WITH CEDILLA>            C7   68   68   68   C3.87    8A.48
<N WITH TILDE>              D1   69   69   69   C3.91    8A.58
<BROKEN BAR>                A6   6A   6A   D0   C2.A6    80.47  ##
,                           2C   6B   6B   6B   2C       6B
%                           25   6C   6C   6C   25       6C
_                           5F   6D   6D   6D   5F       6D
>                           3E   6E   6E   6E   3E       6E
?                           3F   6F   6F   6F   3F       6F
<o WITH STROKE>             F8   70   70   70   C3.B8    8B.67
<E WITH ACUTE>              C9   71   71   71   C3.89    8A.4A
<E WITH CIRCUMFLEX>         CA   72   72   72   C3.8A    8A.51
<E WITH DIAERESIS>          CB   73   73   73   C3.8B    8A.52
<E WITH GRAVE>              C8   74   74   74   C3.88    8A.49
<I WITH ACUTE>              CD   75   75   75   C3.8D    8A.54
<I WITH CIRCUMFLEX>         CE   76   76   76   C3.8E    8A.55
<I WITH DIAERESIS>          CF   77   77   77   C3.8F    8A.56
<I WITH GRAVE>              CC   78   78   78   C3.8C    8A.53
`                           60   79   79   4A   60       79     ##
:                           3A   7A   7A   7A   3A       7A
#                           23   7B   7B   7B   23       7B
@                           40   7C   7C   7C   40       7C
'                           27   7D   7D   7D   27       7D
=                           3D   7E   7E   7E   3D       7E
"                           22   7F   7F   7F   22       7F
<O WITH STROKE>             D8   80   80   80   C3.98    8A.67
a                           61   81   81   81   61       81
b                           62   82   82   82   62       82
c                           63   83   83   83   63       83
d                           64   84   84   84   64       84
e                           65   85   85   85   65       85
f                           66   86   86   86   66       86
g                           67   87   87   87   67       87
h                           68   88   88   88   68       88
i                           69   89   89   89   69       89
<LEFT POINTING GUILLEMET>   AB   8A   8A   8A   C2.AB    80.52
<RIGHT POINTING GUILLEMET>  BB   8B   8B   8B   C2.BB    80.6A
<SMALL LETTER eth>          F0   8C   8C   8C   C3.B0    8B.57
<y WITH ACUTE>              FD   8D   8D   8D   C3.BD    8B.71
<SMALL LETTER thorn>        FE   8E   8E   8E   C3.BE    8B.72
<PLUS-OR-MINUS SIGN>        B1   8F   8F   8F   C2.B1    80.58
<DEGREE SIGN>               B0   90   90   90   C2.B0    80.57
j                           6A   91   91   91   6A       91
k                           6B   92   92   92   6B       92
l                           6C   93   93   93   6C       93
m                           6D   94   94   94   6D       94
n                           6E   95   95   95   6E       95
o                           6F   96   96   96   6F       96
p                           70   97   97   97   70       97
q                           71   98   98   98   71       98
r                           72   99   99   99   72       99
<FEMININE ORDINAL>          AA   9A   9A   9A   C2.AA    80.51
<MASC. ORDINAL INDICATOR>   BA   9B   9B   9B   C2.BA    80.69
<SMALL LIGATURE ae>         E6   9C   9C   9C   C3.A6    8B.47
<CEDILLA>                   B8   9D   9D   9D   C2.B8    80.67
<CAPITAL LIGATURE AE>       C6   9E   9E   9E   C3.86    8A.47
<CURRENCY SIGN>             A4   9F   9F   9F   C2.A4    80.45
<MICRO SIGN>                B5   A0   A0   A0   C2.B5    80.64
~                           7E   A1   A1   FF   7E       A1     ##
s                           73   A2   A2   A2   73       A2
t                           74   A3   A3   A3   74       A3
u                           75   A4   A4   A4   75       A4
v                           76   A5   A5   A5   76       A5
w                           77   A6   A6   A6   77       A6
x                           78   A7   A7   A7   78       A7
y                           79   A8   A8   A8   79       A8
z                           7A   A9   A9   A9   7A       A9
<INVERTED "!" >             A1   AA   AA   AA   C2.A1    80.42
<INVERTED QUESTION MARK>    BF   AB   AB   AB   C2.BF    80.73
<CAPITAL LETTER ETH>        D0   AC   AC   AC   C3.90    8A.57
[                           5B   BA   AD   BB   5B       AD     ** ##
<CAPITAL LETTER THORN>      DE   AE   AE   AE   C3.9E    8A.72
<REGISTERED TRADE MARK>     AE   AF   AF   AF   C2.AE    80.55
<NOT SIGN>                  AC   5F   B0   BA   C2.AC    80.53  ** ##
<POUND SIGN>                A3   B1   B1   B1   C2.A3    80.44
<YEN SIGN>                  A5   B2   B2   B2   C2.A5    80.46
<MIDDLE DOT>                B7   B3   B3   B3   C2.B7    80.66
<COPYRIGHT SIGN>            A9   B4   B4   B4   C2.A9    80.4A
<SECTION SIGN>              A7   B5   B5   B5   C2.A7    80.48
<PARAGRAPH SIGN>            B6   B6   B6   B6   C2.B6    80.65
<FRACTION ONE QUARTER>      BC   B7   B7   B7   C2.BC    80.70
<FRACTION ONE HALF>         BD   B8   B8   B8   C2.BD    80.71
<FRACTION THREE QUARTERS>   BE   B9   B9   B9   C2.BE    80.72
<Y WITH ACUTE>              DD   AD   BA   AD   C3.9D    8A.71  ** ##
<DIAERESIS>                 A8   BD   BB   79   C2.A8    80.49  ** ##
<MACRON>                    AF   BC   BC   A1   C2.AF    80.56  ##
]                           5D   BB   BD   BD   5D       BD     **
<ACUTE ACCENT>              B4   BE   BE   BE   C2.B4    80.63
<MULTIPLICATION SIGN>       D7   BF   BF   BF   C3.97    8A.66
{                           7B   C0   C0   FB   7B       C0     ##
A                           41   C1   C1   C1   41       C1
B                           42   C2   C2   C2   42       C2
C                           43   C3   C3   C3   43       C3
D                           44   C4   C4   C4   44       C4
E                           45   C5   C5   C5   45       C5
F                           46   C6   C6   C6   46       C6
G                           47   C7   C7   C7   47       C7
H                           48   C8   C8   C8   48       C8
I                           49   C9   C9   C9   49       C9
<SOFT HYPHEN>               AD   CA   CA   CA   C2.AD    80.54
<o WITH CIRCUMFLEX>         F4   CB   CB   CB   C3.B4    8B.63
<o WITH DIAERESIS>          F6   CC   CC   CC   C3.B6    8B.65
<o WITH GRAVE>              F2   CD   CD   CD   C3.B2    8B.59
<o WITH ACUTE>              F3   CE   CE   CE   C3.B3    8B.62
<o WITH TILDE>              F5   CF   CF   CF   C3.B5    8B.64
}                           7D   D0   D0   FD   7D       D0     ##
J                           4A   D1   D1   D1   4A       D1
K                           4B   D2   D2   D2   4B       D2
L                           4C   D3   D3   D3   4C       D3
M                           4D   D4   D4   D4   4D       D4
N                           4E   D5   D5   D5   4E       D5
O                           4F   D6   D6   D6   4F       D6
P                           50   D7   D7   D7   50       D7
Q                           51   D8   D8   D8   51       D8
R                           52   D9   D9   D9   52       D9
<SUPERSCRIPT ONE>           B9   DA   DA   DA   C2.B9    80.68
<u WITH CIRCUMFLEX>         FB   DB   DB   DB   C3.BB    8B.6A
<u WITH DIAERESIS>          FC   DC   DC   DC   C3.BC    8B.70
<u WITH GRAVE>              F9   DD   DD   C0   C3.B9    8B.68  ##
<u WITH ACUTE>              FA   DE   DE   DE   C3.BA    8B.69
<y WITH DIAERESIS>          FF   DF   DF   DF   C3.BF    8B.73
\                           5C   E0   E0   BC   5C       E0     ##
<DIVISION SIGN>             F7   E1   E1   E1   C3.B7    8B.66
S                           53   E2   E2   E2   53       E2
T                           54   E3   E3   E3   54       E3
U                           55   E4   E4   E4   55       E4
V                           56   E5   E5   E5   56       E5
W                           57   E6   E6   E6   57       E6
X                           58   E7   E7   E7   58       E7
Y                           59   E8   E8   E8   59       E8
Z                           5A   E9   E9   E9   5A       E9
<SUPERSCRIPT TWO>           B2   EA   EA   EA   C2.B2    80.59
<O WITH CIRCUMFLEX>         D4   EB   EB   EB   C3.94    8A.63
<O WITH DIAERESIS>          D6   EC   EC   EC   C3.96    8A.65
<O WITH GRAVE>              D2   ED   ED   ED   C3.92    8A.59
<O WITH ACUTE>              D3   EE   EE   EE   C3.93    8A.62
<O WITH TILDE>              D5   EF   EF   EF   C3.95    8A.64
0                           30   F0   F0   F0   30       F0
1                           31   F1   F1   F1   31       F1
2                           32   F2   F2   F2   32       F2
3                           33   F3   F3   F3   33       F3
4                           34   F4   F4   F4   34       F4
5                           35   F5   F5   F5   35       F5
6                           36   F6   F6   F6   36       F6
7                           37   F7   F7   F7   37       F7
8                           38   F8   F8   F8   38       F8
9                           39   F9   F9   F9   39       F9
<SUPERSCRIPT THREE>         B3   FA   FA   FA   C2.B3    80.62
<U WITH CIRCUMFLEX>         DB   FB   FB   DD   C3.9B    8A.6A  ##
<U WITH DIAERESIS>          DC   FC   FC   FC   C3.9C    8A.70
<U WITH GRAVE>              D9   FD   FD   E0   C3.99    8A.68  ##
<U WITH ACUTE>              DA   FE   FE   FE   C3.9A    8A.69
<APC>                       9F   FF   FF   5F   C2.9F    FF     ##

識別字元碼組

可以判斷您正在使用哪一個字元集。但首先您需要非常非常確定您需要這麼做。如果您不需要測試字元集並執行不同的動作,您的程式碼會更簡單且可能更具可攜性。實際上,只有極少數的情況無法輕鬆撰寫可攜到所有字元集的直線程式碼。請參閱 perluniintro 中的「Unicode 和 EBCDIC」,了解如何以可攜方式指定字元。

但在某些情況下,您可能想知道您正在使用哪一個字元集。一個可能的範例是在效能至關重要的內部迴圈中執行 排序

若要判斷您是否在 ASCII 或 EBCDIC 下執行,您可以使用 ord()chr() 的傳回值來測試一個或多個字元值。例如

$is_ascii  = "A" eq chr(65);
$is_ebcdic = "A" eq chr(193);
$is_ascii  = ord("A") == 65;
$is_ebcdic = ord("A") == 193;

甚至更不需要區分 EBCDIC 編碼頁,但要這麼做,請嘗試查看它們之間不同的其中一個或多個字元。

$is_ascii           = ord('[') == 91;
$is_ebcdic_37       = ord('[') == 186;
$is_ebcdic_1047     = ord('[') == 173;
$is_ebcdic_POSIX_BC = ord('[') == 187;

不過,撰寫類似這樣的測試是不明智的

$is_ascii = "\r" ne chr(13);  #  WRONG
$is_ascii = "\n" ne chr(10);  #  ILL ADVISED

顯然,第一個測試無法區分大多數 ASCII 平台與 CCSID 0037、1047 或 POSIX-BC EBCDIC 平台,因為 "\r" eq chr(13) 在所有這些編碼字元集中都是如此。但也要注意,因為 "\n"chr(13),而 "\r" 是舊 Macintosh(一個 ASCII 平台)上的 chr(10),所以第二個 $is_ascii 測試將會導致問題。

若要判斷 perl 是否在 EBCDIC 編碼頁下建置,您可以使用 Config 模組,如下所示

use Config;
$is_ebcdic = $Config{'ebcdic'} eq 'define';

轉換

utf8::unicode_to_native()utf8::native_to_unicode()

這些函式會在一個編碼中取得輸入數值碼點,並傳回其在另一個編碼中的等值。

請參閱 utf8

tr///

若要將字元串從一個字元集轉換到另一個字元集,只需要一個數字清單,例如上表右欄中的清單,以及 Perl 的 tr/// 算子。表格中的資料以 ASCII/Latin1 順序排列,因此 EBCDIC 欄提供易於使用的 ASCII/Latin1 轉 EBCDIC 作業,而且也容易反向執行。

例如,要將 ASCII/Latin1 轉換為編碼頁 037,請採用食譜 2 輸出中的第二個數字欄位的輸出(修改為加入 "\" 字元),並在 tr/// 中使用,如下所示

$cp_037 =
'\x00\x01\x02\x03\x37\x2D\x2E\x2F\x16\x05\x25\x0B\x0C\x0D\x0E\x0F' .
'\x10\x11\x12\x13\x3C\x3D\x32\x26\x18\x19\x3F\x27\x1C\x1D\x1E\x1F' .
'\x40\x5A\x7F\x7B\x5B\x6C\x50\x7D\x4D\x5D\x5C\x4E\x6B\x60\x4B\x61' .
'\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\x7A\x5E\x4C\x7E\x6E\x6F' .
'\x7C\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xD1\xD2\xD3\xD4\xD5\xD6' .
'\xD7\xD8\xD9\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xBA\xE0\xBB\xB0\x6D' .
'\x79\x81\x82\x83\x84\x85\x86\x87\x88\x89\x91\x92\x93\x94\x95\x96' .
'\x97\x98\x99\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xC0\x4F\xD0\xA1\x07' .
'\x20\x21\x22\x23\x24\x15\x06\x17\x28\x29\x2A\x2B\x2C\x09\x0A\x1B' .
'\x30\x31\x1A\x33\x34\x35\x36\x08\x38\x39\x3A\x3B\x04\x14\x3E\xFF' .
'\x41\xAA\x4A\xB1\x9F\xB2\x6A\xB5\xBD\xB4\x9A\x8A\x5F\xCA\xAF\xBC' .
'\x90\x8F\xEA\xFA\xBE\xA0\xB6\xB3\x9D\xDA\x9B\x8B\xB7\xB8\xB9\xAB' .
'\x64\x65\x62\x66\x63\x67\x9E\x68\x74\x71\x72\x73\x78\x75\x76\x77' .
'\xAC\x69\xED\xEE\xEB\xEF\xEC\xBF\x80\xFD\xFE\xFB\xFC\xAD\xAE\x59' .
'\x44\x45\x42\x46\x43\x47\x9C\x48\x54\x51\x52\x53\x58\x55\x56\x57' .
'\x8C\x49\xCD\xCE\xCB\xCF\xCC\xE1\x70\xDD\xDE\xDB\xDC\x8D\x8E\xDF';

my $ebcdic_string = $ascii_string;
eval '$ebcdic_string =~ tr/\000-\377/' . $cp_037 . '/';

要從 EBCDIC 037 轉換為 ASCII,只需反轉 tr/// 參數的順序,如下所示

my $ascii_string = $ebcdic_string;
eval '$ascii_string =~ tr/' . $cp_037 . '/\000-\377/';

同樣地,可以採用食譜 2 中第三個數字欄位的輸出,以取得 $cp_1047 表格。食譜 2 輸出的第四個數字欄位可以提供一個適合轉碼的 $cp_posix_bc 表格。

如果您想查看反向表格,您必須先在食譜 4、5 或 6 中根據所需的數字欄位進行排序,然後採用第一個數字欄位的輸出。

iconv

XPG 可操作性通常表示存在一個可從 shell 或 C 函式庫取得的 iconv 實用程式。請參閱您的系統文件,以取得關於 iconv 的資訊。

在 OS/390 或 z/OS 上,請參閱 iconv(1) 手冊頁。從 perl 內部呼叫 iconv shell 實用程式的一種方法是

# OS/390 or z/OS example
$ascii_data = `echo '$ebcdic_data'| iconv -f IBM-1047 -t ISO8859-1`

或反向對應

# OS/390 or z/OS example
$ebcdic_data = `echo '$ascii_data'| iconv -f ISO8859-1 -t IBM-1047`

對於其他基於 Perl 的轉換選項,請參閱 CPAN 上的 Convert::* 模組。

C RTL

OS/390 和 z/OS C 執行時期函式庫提供 _atoe()_etoa() 函式。

運算子差異

.. 範圍運算子在 EBCDIC 平台上小心處理特定字元範圍。例如,下列陣列在 EBCDIC 平台或 ASCII 平台上將有二十六個元素

@alphabet = ('A'..'Z');   #  $#alphabet == 25

當在 EBCDIC 平台上執行的 Perl 程式中對字串或字元資料進行運算時,位元運算子(例如 & ^ |)可能會傳回與在 ASCII 平台上執行時不同的結果。以下是從 perlop 中改編的範例

# EBCDIC-based examples
print "j p \n" ^ " a h";                      # prints "JAPH\n"
print "JA" | "  ph\n";                        # prints "japh\n"
print "JAPH\nJunk" & "\277\277\277\277\277";  # prints "japh\n";
print 'p N$' ^ " E<H\n";                      # prints "Perl\n";

ASCII 表中 32 個 C0 控制字元的有趣屬性是它們可以在 Perl 中「實際上」建構為控制字元,例如 (chr(0) 等於 \c@)> (chr(1) 等於 \cA)>,以此類推。EBCDIC 平台上的 Perl 已移植,可以將 \c@ 轉換為 chr(0),將 \cA 轉換為 chr(1) 等,但產生的字元取決於您使用的代碼頁。下表使用控制字元的標準縮寫。POSIX-BC 和 1047 組在這個範圍內完全相同,只在一個位置(十進制 21)與 0037 組不同。請注意,行終止字元可以在 ASCII 平台上由 \cJ 產生,但在 1047 或 POSIX-BC 平台上由 \cU 產生,並且不能在 0037 平台上作為 "\c.letter." 控制字元產生。另請注意,\c\ 不能是字串或正規表示式的最後一個元素,因為它會吸收終止符。但是 \c\XFILE SEPARATORX 的串接,對於所有 X 皆成立。ASCII 上的異常值 \c? 會產生非 C0 控制字元 DEL,在 EBCDIC 上會產生異常值控制字元 APC,它不在連續控制字元的區塊中。請注意,這一點的微妙之處在於 ASCII 平台上的 \c? 是 ASCII 字元,而它不等於 EBCDIC 平台上的任何 ASCII 字元。

chr   ord   8859-1    0037    1047 && POSIX-BC
-----------------------------------------------------------------------
\c@     0   <NUL>     <NUL>        <NUL>
\cA     1   <SOH>     <SOH>        <SOH>
\cB     2   <STX>     <STX>        <STX>
\cC     3   <ETX>     <ETX>        <ETX>
\cD     4   <EOT>     <ST>         <ST>
\cE     5   <ENQ>     <HT>         <HT>
\cF     6   <ACK>     <SSA>        <SSA>
\cG     7   <BEL>     <DEL>        <DEL>
\cH     8   <BS>      <EPA>        <EPA>
\cI     9   <HT>      <RI>         <RI>
\cJ    10   <LF>      <SS2>        <SS2>
\cK    11   <VT>      <VT>         <VT>
\cL    12   <FF>      <FF>         <FF>
\cM    13   <CR>      <CR>         <CR>
\cN    14   <SO>      <SO>         <SO>
\cO    15   <SI>      <SI>         <SI>
\cP    16   <DLE>     <DLE>        <DLE>
\cQ    17   <DC1>     <DC1>        <DC1>
\cR    18   <DC2>     <DC2>        <DC2>
\cS    19   <DC3>     <DC3>        <DC3>
\cT    20   <DC4>     <OSC>        <OSC>
\cU    21   <NAK>     <NEL>        <LF>              **
\cV    22   <SYN>     <BS>         <BS>
\cW    23   <ETB>     <ESA>        <ESA>
\cX    24   <CAN>     <CAN>        <CAN>
\cY    25   <EOM>     <EOM>        <EOM>
\cZ    26   <SUB>     <PU2>        <PU2>
\c[    27   <ESC>     <SS3>        <SS3>
\c\X   28   <FS>X     <FS>X        <FS>X
\c]    29   <GS>      <GS>         <GS>
\c^    30   <RS>      <RS>         <RS>
\c_    31   <US>      <US>         <US>
\c?    *    <DEL>     <APC>        <APC>

* 注意:\c? 在 ASCII 平台上對應序號 127(DEL),但由於序號 127 在 EBCDIC 電腦上不是控制字元,因此 \c? 在 EBCDIC 電腦上對應序號 255(0037 和 1047)或 95(POSIX-BC)的 APC

函數差異

chr()

必須提供 chr() 一個 EBCDIC 碼數字引數,才能在 EBCDIC 平台上產生所需的字元傳回值。例如

$CAPITAL_LETTER_A = chr(193);
ord()

ord() 會在 EBCDIC 平台上傳回 EBCDIC 碼數字值。例如

$the_number_193 = ord("A");
pack()

pack()"c""C" 範本取決於字元集編碼。EBCDIC 上的使用範例包括

$foo = pack("CCCC",193,194,195,196);
# $foo eq "ABCD"
$foo = pack("C4",193,194,195,196);
# same thing

$foo = pack("ccxxcc",193,194,195,196);
# $foo eq "AB\0\0CD"

"U" 範本已移植到所有平台上,表示「Unicode」,因此

pack("U", 65) eq 'A'

在所有平台上都成立。如果您想要低 256 的原生碼點,請使用 "W" 範本。這表示等價關係

pack("W", ord($character)) eq $character
unpack("W", $character) == ord $character

會成立。

print()

必須小心傳遞給 print 的純量和字串,其中包含 ASCII 編碼。發生這種情況的一個常見地方是在 CGI 程式寫作的 MIME 類型標頭輸出中。例如,許多 Perl 程式設計指南建議類似於

print "Content-type:\ttext/html\015\012\015\012";
# this may be wrong on EBCDIC

您可以改寫為

print "Content-type:\ttext/html\r\n\r\n"; # OK for DGW et al

並讓它可移植地工作。

這是因為從 EBCDIC 轉換為 ASCII 是由網路伺服器在此情況下完成的。請參閱網路伺服器的文件以取得進一步的詳細資訊。

printf()

在 EBCDIC 平台上執行時,可以將字元轉換為數字,反之亦然的格式將與其 ASCII 對應項不同。範例包括

printf("%c%c%c",193,194,195);  # prints ABC
sort()

EBCDIC 排序結果可能與 ASCII 排序結果不同,特別是對於混合大小寫的字串。這在 下方有更詳細的討論。

sprintf()

請參閱上面 "printf()" 的討論。sprintf 使用範例如下

$CAPITAL_LETTER_A = sprintf("%c",193);
unpack()

請參閱上面 "pack()" 的討論。

請注意,透過指定 Unicode 數字和使用轉換函數,可以為這些函數撰寫可移植的程式碼

printf("%c",utf8::unicode_to_native(65));  # prints A on all
                                           # platforms
print utf8::native_to_unicode(ord("A"));   # Likewise, prints 65

請參閱 "perluniintro 中的 Unicode 和 EBCDIC""轉換" 以取得其他選項。

正規表示式差異

您可以像 ASCII 平台上的某人一樣撰寫正規表示式。但請記住,使用八進位或十六進位表示法來指定特定代碼點會提供 EBCDIC 代碼頁原生對應的字元。(這也適用於所有雙引號字串。)如果您想可移植地撰寫,請在您會使用 \x{...} 的任何地方使用 \N{U+...} 表示法,並且完全不要使用八進位表示法。

從 Perl v5.22 開始,這適用於括號字元類別中的範圍。例如,如果您說 qr/[\N{U+20}-\N{U+7F}]/,它表示字元 \N{U+20}\N{U+21}、...、\N{U+7F}。此範圍是 ASCII 字元集包含的所有可列印字元。

在 v5.22 之前,您無法可移植地指定任何範圍,除了 (從 Perl v5.5.3 開始) [A-Z][a-z] 範圍的所有子集都被特別編碼為不選取間隙字元。例如,介於 "I" 和 "J" 之間的字元,例如 "ô" (帶圓音符號的 o) 將不會與正規表示式範圍 /[H-K]/ 相符。但是,如果範圍端點之一明確為數字 (且兩者都沒有由 \N{U+...} 指定),則會比對間隙字元

/[\x89-\x91]/

將比對 \x8e,即使 \x89 是 "i",\x91 是 "j",而 \x8e 從字母觀點來看是間隙字元。

另一個要注意的建構是十六進位 (除非您使用 \N{U+...}) 或八進位常數在正規表示式中不當使用。考慮下列子集

sub is_c0 {
    my $char = substr(shift,0,1);
    $char =~ /[\000-\037]/;
}

sub is_print_ascii {
    my $char = substr(shift,0,1);
    $char =~ /[\040-\176]/;
}

sub is_delete {
    my $char = substr(shift,0,1);
    $char eq "\177";
}

sub is_c1 {
    my $char = substr(shift,0,1);
    $char =~ /[\200-\237]/;
}

sub is_latin_1 {    # But not ASCII; not C1
    my $char = substr(shift,0,1);
    $char =~ /[\240-\377]/;
}

這些僅在 ASCII 平台上有效。從 Perl v5.22 開始,只需將八進位常數變更為等效的 \N{U+...} 值即可攜帶

sub is_c0 {
    my $char = substr(shift,0,1);
    $char =~ /[\N{U+00}-\N{U+1F}]/;
}

sub is_print_ascii {
    my $char = substr(shift,0,1);
    $char =~ /[\N{U+20}-\N{U+7E}]/;
}

sub is_delete {
    my $char = substr(shift,0,1);
    $char eq "\N{U+7F}";
}

sub is_c1 {
    my $char = substr(shift,0,1);
    $char =~ /[\N{U+80}-\N{U+9F}]/;
}

sub is_latin_1 {    # But not ASCII; not C1
    my $char = substr(shift,0,1);
    $char =~ /[\N{U+A0}-\N{U+FF}]/;
}

以下是撰寫它們的一些替代攜帶方式

sub Is_c0 {
    my $char = substr(shift,0,1);
    return $char =~ /[[:cntrl:]]/a && ! Is_delete($char);

    # Alternatively:
    # return $char =~ /[[:cntrl:]]/
    #        && $char =~ /[[:ascii:]]/
    #        && ! Is_delete($char);
}

sub Is_print_ascii {
    my $char = substr(shift,0,1);

    return $char =~ /[[:print:]]/a;

    # Alternatively:
    # return $char =~ /[[:print:]]/ && $char =~ /[[:ascii:]]/;

    # Or
    # return $char
    #      =~ /[ !"\#\$%&'()*+,\-.\/0-9:;<=>?\@A-Z[\\\]^_`a-z{|}~]/;
}

sub Is_delete {
    my $char = substr(shift,0,1);
    return utf8::native_to_unicode(ord $char) == 0x7F;
}

sub Is_c1 {
    use feature 'unicode_strings';
    my $char = substr(shift,0,1);
    return $char =~ /[[:cntrl:]]/ && $char !~ /[[:ascii:]]/;
}

sub Is_latin_1 {    # But not ASCII; not C1
    use feature 'unicode_strings';
    my $char = substr(shift,0,1);
    return ord($char) < 256
           && $char !~ /[[:ascii:]]/
           && $char !~ /[[:cntrl:]]/;
}

撰寫 Is_latin_1() 的另一種方式是明確使用範圍內的字元

sub Is_latin_1 {
    my $char = substr(shift,0,1);
    $char =~ /[ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ]
              [ÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ]/x;
}

儘管該表單可能會在網路傳輸中遇到問題 (由於 8 位元字元的出現) 或在非 ISO-Latin 字元集上。但它確實允許 Is_c1 重新撰寫,以便在沒有 'unicode_strings' (早於 v5.14) 的 Perl 上執行

sub Is_latin_1 {    # But not ASCII; not C1
    my $char = substr(shift,0,1);
    return ord($char) < 256
           && $char !~ /[[:ascii:]]/
           && ! Is_latin1($char);
}

SOCKETS

大多數 socket 程式設計假設網路位元組順序中的 ASCII 字元編碼。例外情況包括在主機網路伺服器下撰寫 CGI 腳本,其中伺服器可能會為您處理轉換。大多數主機網路伺服器會在輸出時將 EBCDIC 資料轉換為 ISO-8859-1 或 Unicode。

SORTING

基於 ASCII 的字元集和 EBCDIC 字元集之間的一個重大差異是在原生順序中排序時字元的相對位置。最令人關注的是大小寫字母、數字和底線 ("_")。在 ASCII 平台上,原生排序順序是數字出現在大寫字母之前,大寫字母出現在底線之前,底線出現在小寫字母之前。在 EBCDIC 上,底線優先,然後是小寫字母,然後是大寫字母,最後是數字。如果在基於 ASCII 的平台上排序,則醫師的兩個字母縮寫會出現在驅動器的兩個字母縮寫之前;也就是說

@sorted = sort(qw(Dr. dr.));  # @sorted holds ('Dr.','dr.') on ASCII,
                                 # but ('dr.','Dr.') on EBCDIC

EBCDIC 中小寫字母在大寫字母之前的特性甚至會傳遞到拉丁文 1 EBCDIC 頁面,例如 0037 和 1047。一個例子是 "Ë" (E WITH DIAERESIS,203) 出現在 "ë" (e WITH DIAERESIS,235) 之前在 ASCII 平台上,但後者 (83) 出現在前者 (115) 之前在 EBCDIC 平台上。(精明的讀者會注意到 "ß" SMALL LETTER SHARP S 的大寫版本只是 "SS",而 "ÿ" (小寫 y WITH DIAERESIS) 和 "µ" (MICRO SIGN) 的大寫版本不在 0..255 範圍內,但在 Unicode 中,在啟用 Unicode 的 Perl 中)。

排序順序會造成在 ASCII 平台上取得的結果與在 EBCDIC 平台上取得的結果之間的差異。以下是一些處理這些差異的建議。

忽略 ASCII 與 EBCDIC 排序差異。

這是運算成本最低的策略。它可能需要一些使用者教育。

使用排序輔助函式

這是完全通用的,但運算成本最高的策略。選擇一個字元集並在每次排序比較時轉換為該字元集。以下是轉換為 ASCII 排序順序的完整範例

sub native_to_uni($) {
   my $string = shift;

   # Saves time on an ASCII platform
   return $string if ord 'A' ==  65;

   my $output = "";
   for my $i (0 .. length($string) - 1) {
       $output
          .= chr(utf8::native_to_unicode(ord(substr($string, $i, 1))));
   }

   # Preserve utf8ness of input onto the output, even if it didn't need
   # to be utf8
   utf8::upgrade($output) if utf8::is_utf8($string);

   return $output;
}

sub ascii_order {   # Sort helper
   return native_to_uni($a) cmp native_to_uni($b);
}

sort ascii_order @list;

單一大小寫然後排序資料 (對於非數字、非底線)

如果您不在乎數字和底線的排序位置,您可以執行類似這樣的操作

sub case_insensitive_order {   # Sort helper
   return lc($a) cmp lc($b)
}

sort case_insensitive_order @list;

如果效能是一個問題,而且您不在乎輸出是否與輸入大小寫相同,請使用 tr/// 轉換為資料中最常用的大小寫。如果資料主要是非拉丁碼 1 的大寫,則套用 tr/[a-z]/[A-Z]/,然後 sort()。如果資料主要是非拉丁碼 1 的小寫,則在排序之前套用 tr/[A-Z]/[a-z]/。如果資料主要是大寫並包含拉丁碼 1 字元,則套用

tr/[a-z]/[A-Z]/;
tr/[àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþ]/[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ/;
s/ß/SS/g;

然後 sort()。如果您有選擇,最好將所有內容轉換為小寫,以避免兩個拉丁碼 1 字元的大寫在拉丁碼 1 之外造成的問題:「ÿ」(小寫 帶分音符號的 y)和「µ」(微小符號)。如果您確實需要轉換為大寫,您可以使用啟用 Unicode 的 Perl 執行

tr/ÿ/\x{178}/;
tr/µ/\x{39C}/;

僅在一個平台類型上執行排序。

此策略可以使用網路連線。因此,它的運算成本會很高。

轉換格式

有許多方法可以用於轉換資料,這些方法使用字元集內對應,並服務於各種目的。排序已在上一節中討論,接下來將討論一些其他更流行的對應技術。

URL 解碼和編碼

請注意,一些 URL 中包含十六進位 ASCII 碼點,以嘗試克服字元或協定限制問題。例如,並非每個鍵盤都有波浪號字元,因此形式為

http://www.pvhp.com/~pvhp/

也可以表示為

http://www.pvhp.com/%7Epvhp/

http://www.pvhp.com/%7epvhp/

其中 7E 是 "~" 的十六進位 ASCII 碼點。以下是使用任何 EBCDIC 碼頁解碼此類 URL 的範例

$url = 'http://www.pvhp.com/%7Epvhp/';
$url =~ s/%([0-9a-fA-F]{2})/
          pack("c",utf8::unicode_to_native(hex($1)))/xge;

相反地,以下是使用任何 EBCDIC 碼頁對此類 URL 進行編碼任務的部分解決方案

$url = 'http://www.pvhp.com/~pvhp/';
# The following regular expression does not address the
# mappings for: ('.' => '%2E', '/' => '%2F', ':' => '%3A')
$url =~ s/([\t "#%&\(\),;<=>\?\@\[\\\]^`{|}~])/
           sprintf("%%%02X",utf8::native_to_unicode(ord($1)))/xge;

更完整的解決方案會將 URL 分割成組成部分,並僅對適當的部分套用完整的 s/// 替換。

uu 編碼和解碼

u 範本用於 pack()unpack() 會以等同於其 ASCII 對應字元的 EBCDIC 字元呈現 EBCDIC 資料。例如,下列程式碼會在 ASCII 或 EBCDIC 電腦上列印「Yes indeed\n」

$all_byte_chrs = '';
for (0..255) { $all_byte_chrs .= chr($_); }
$uuencode_byte_chrs = pack('u', $all_byte_chrs);
($uu = <<'ENDOFHEREDOC') =~ s/^\s*//gm;
M``$"`P0%!@<("0H+#`T.#Q`1$A,4%187&!D:&QP='A\@(2(C)"4F)R@I*BLL
M+2XO,#$R,S0U-C<X.3H[/#T^/T!!0D-$149'2$E*2TQ-3D]045)35%565UA9
M6EM<75Y?8&%B8V1E9F=H:6IK;&UN;W!Q<G-T=79W>'EZ>WQ]?G^`@8*#A(6&
MAXB)BHN,C8Z/D)&2DY25EI>8F9J;G)V>GZ"AHJ.DI::GJ*FJJZRMKJ^PL;*S
MM+6VM[BYNKN\O;Z_P,'"P\3%QL?(R<K+S,W.S]#1TM/4U=;7V-G:V]S=WM_@
?X>+CY.7FY^CIZNOL[>[O\/'R\_3U]O?X^?K[_/W^_P``
ENDOFHEREDOC
if ($uuencode_byte_chrs eq $uu) {
    print "Yes ";
}
$uudecode_byte_chrs = unpack('u', $uuencode_byte_chrs);
if ($uudecode_byte_chrs eq $all_byte_chrs) {
    print "indeed\n";
}

以下是可以在 EBCDIC 上運作的極簡 uudecoder

#!/usr/local/bin/perl
$_ = <> until ($mode,$file) = /^begin\s*(\d*)\s*(\S*)/;
open(OUT, "> $file") if $file ne "";
while(<>) {
    last if /^end/;
    next if /[a-z]/;
    next unless int((((utf8::native_to_unicode(ord()) - 32 ) & 077)
                                                           + 2) / 3)
                == int(length() / 4);
    print OUT unpack("u", $_);
}
close(OUT);
chmod oct($mode), $file;

Quoted-Printable 編碼和解碼

在 ASCII 編碼的平台上,可以使用下列方式移除可列印集外的字元

# This QP encoder works on ASCII only
$qp_string =~ s/([=\x00-\x1F\x80-\xFF])/
                sprintf("=%02X",ord($1))/xge;

從 Perl v5.22 開始,這可以輕易地變更,以便在 ASCII 和 EBCDIC 平台上可攜式運作。

# This QP encoder works on both ASCII and EBCDIC
$qp_string =~ s/([=\N{U+00}-\N{U+1F}\N{U+80}-\N{U+FF}])/
                sprintf("=%02X",ord($1))/xge;

對於較早的 Perl,可以在 ASCII 和 EBCDIC 平台上運作的 QP 編碼器會類似下列程式碼

$delete = utf8::unicode_to_native(ord("\x7F"));
$qp_string =~
  s/([^[:print:]$delete])/
     sprintf("=%02X",utf8::native_to_unicode(ord($1)))/xage;

(儘管在實際程式碼中,替換可能會在 EBCDIC 分支中使用函式呼叫進行,並在 ASCII 分支中單獨進行,而不會產生身分對應的開銷;在 Perl v5.22 中,身分對應會進行最佳化,因此不會產生開銷,但上述替代方案較為簡單,而且在 v5.22 中也可用)。

此類 QP 字串可以使用下列方式解碼

# This QP decoder is limited to ASCII only
$string =~ s/=([[:xdigit:][[:xdigit:])/chr hex $1/ge;
$string =~ s/=[\n\r]+$//;

可以在 ASCII 和 EBCDIC 平台上運作的 QP 解碼器會類似下列程式碼

$string =~ s/=([[:xdigit:][:xdigit:]])/
                            chr utf8::native_to_unicode(hex $1)/xge;
$string =~ s/=[\n\r]+$//;

凱撒密碼

將字母表向後或向前移動一個或多個字元以進行加密的做法可以追溯到數千年前,而且蓋尤斯·尤利烏斯·凱撒在他的高盧戰記中明確地詳細說明了這種做法。單一字母表移動有時稱為旋轉,而移動量會在字串「rot」或「rot$n」後以數字 $n 表示。Rot0 和 rot26 會在拉丁字母表的 26 個字母英文版本上指定身分對應。Rot13 具有有趣的特性,即交替後續呼叫會是身分對應(因此 rot13 是其在 26 個字母旋轉群組中非平凡的逆運算)。因此,以下是可以在 ASCII 和 EBCDIC 平台上運作的 rot13 編碼器和解碼器

#!/usr/local/bin/perl

while(<>){
    tr/n-za-mN-ZA-M/a-zA-Z/;
    print;
}

單行形式

perl -ne 'tr/n-za-mN-ZA-M/a-zA-Z/;print'

雜湊順序和校驗和

Perl 故意將雜湊順序隨機化,以確保 ASCII 和 EBCDIC 平台上的安全性。

將同一檔案轉換為 ASCII 和 EBCDIC 後,其校驗和將有所不同,反之亦然。

I18N 和 L10N

國際化 (I18N) 和在地化 (L10N) 至少在原則上受支援,即使是在 EBCDIC 平台上。詳細資訊取決於系統,並在下列 「作業系統問題」 區段中討論。

多位元組字元集

Perl 使用 UTF-EBCDIC,這是一種多位元組編碼。在早於 v5.22 的 Perl 版本中,可能會出現各種相關錯誤。

舊版多位元組 EBCDIC 程式碼頁 XXX。

作業系統問題

對於 EBCDIC Perl 程式設計人員來說,可能會有一些系統相關問題需要關注。

OS/400

PASE

PASE 環境是 OS/400 的執行時期環境,可以在 OS/400 中執行為 PowerPC AIX 建置的可執行檔;請參閱 perlos400。PASE 是以 ASCII 為基礎,而不是像 ILE 一樣以 EBCDIC 為基礎。

IFS 存取

XXX。

OS/390、z/OS

Perl 在 Unix Systems Services 或 USS 下執行。

sigaction

SA_SIGINFO 可能會產生分段錯誤。

chcp

chcp 受支援作為一個 shell 工具程式,用於顯示和變更自己的程式碼頁。另請參閱 chcp(1)

資料集存取

對於順序資料集存取,請嘗試

my @ds_records = `cat //DSNAME`;

my @ds_records = `cat //'HLQ.DSNAME'`;

另請參閱 CPAN 上的 OS390::Stdio 模組。

iconv

iconv 受支援作為 shell 工具程式和 C RTL 常式。另請參閱 iconv(1)iconv(3) 手冊頁面。

地區設定

支援區域設定。當區域設定是另一個 EBCDIC 編碼頁面時,可能會發生故障,因為其他位置有一些 編碼頁面變體字元

目前沒有任何真正的 UTF-8 區域設定,即使有些區域設定名稱包含字串「UTF-8」。

請參閱 perllocale 以取得有關區域設定的資訊。L10N 檔案位於 /usr/nls/locale 中。$Config{d_setlocale} 在 OS/390 或 z/OS 上為 'define'

POSIX-BC?

XXX。

錯誤

另請參閱

perllocaleperlfuncperlunicodeutf8

參考資料

http://std.dkuug.dk/i18n/charmaps

https://www.unicode.org/

https://www.unicode.org/reports/tr16/

https://www.sr-ix.com/Archive/CharCodeHist/index.html ASCII:資訊滲透的美國標準代碼 湯姆·詹寧斯,1999 年 9 月。

Unicode 標準,版本 3.0 Unicode 聯盟,莉莎·摩爾編輯,ISBN 0-201-61633-5,艾迪生·韋斯利開發人員出版社,2000 年 2 月。

CDRA:IBM - 字元資料表示架構 - 參考和註冊,IBM SC09-2190-00,1996 年 12 月。

「揭開字元集的神秘面紗」,安德莉亞·文恩,多語言運算與技術,#26 第 10 卷第 4 期,1999 年 8 月/9 月;ISSN 1523-0309;多語言運算公司,美國愛達荷州桑德波因特。

代碼、密碼和其他隱密和秘密通訊 弗雷德·B·賴克森,ISBN 1-57912-040-7,黑狗與李文索出版社,1998 年。

http://www.bobbemer.com/P-BIT.HTM IBM - EBCDIC 和 P-bit;史上最大的電腦錯誤 羅伯特·貝默。

歷史

2001 年 4 月 15 日:將 UTF-8 和 UTF-EBCDIC 加入主表,pvhp。

作者

Peter Prymmer pvhp@best.com 於 1999 年和 2000 年撰寫本文,並得到 Chris Leach 和 André Pirard A.Pirard@ulg.ac.be 提供的 CCSID 0819 和 0037 協助,以及 Thomas Dorner Thomas.Dorner@start.de 提供的 POSIX-BC 協助。也要感謝 Vickie Cooper、Philip Newton、William Raffloer 和 Joe Smith。本文中使用的商標、註冊商標、服務標誌和註冊服務標誌為其各自所有者的財產。

目前由 Perl5 Porters 維護。