📄 perlebcdic.pod
字号:
=head1 NAMEperlebcdic - Considerations for running Perl on EBCDIC platforms=head1 DESCRIPTIONAn exploration of some of the issues facing Perl programmerson EBCDIC based computers. We do not cover localization, internationalization, or multi byte character set issues otherthan some discussion of UTF-8 and UTF-EBCDIC.Portions that are still incomplete are marked with XXX.=head1 COMMON CHARACTER CODE SETS=head2 ASCIIThe American Standard Code for Information Interchange is a set ofintegers running from 0 to 127 (decimal) that imply character interpretation by the display and other system(s) of computers. The range 0..127 can be covered by setting the bits in a 7-bit binary digit, hence the set is sometimes referred to as a "7-bit ASCII". ASCII was described by the American National Standards Institute document ANSI X3.4-1986. It was also described by ISO 646:1991 (with localization for currency symbols). The full ASCII set is given in the table below as the first 128 elements. Languages that can be written adequately with the characters in ASCII include English, Hawaiian, Indonesian, Swahili and some Native American languages.There are many character sets that extend the range of integersfrom 0..2**7-1 up to 2**8-1, or 8 bit bytes (octets if you prefer).One common one is the ISO 8859-1 character set.=head2 ISO 8859The ISO 8859-$n are a collection of character code sets from the International Organization for Standardization (ISO) each of which adds characters to the ASCII set that are typically found in European languages many of which are based on the Roman, or Latin, alphabet.=head2 Latin 1 (ISO 8859-1)A particular 8-bit extension to ASCII that includes grave and acute accented Latin characters. Languages that can employ ISO 8859-1 include all the languages covered by ASCII as well as Afrikaans, Albanian, Basque, Catalan, Danish, Faroese, Finnish, Norwegian, Portuguese, Spanish, and Swedish. Dutch is covered albeit without the ij ligature. French is covered too but without the oe ligature. German can use ISO 8859-1 but must do so without German-stylequotation marks. This set is based on Western European extensions to ASCII and is commonly encountered in world wide web work.In IBM character code set identification terminology ISO 8859-1 isalso known as CCSID 819 (or sometimes 0819 or even 00819).=head2 EBCDICThe Extended Binary Coded Decimal Interchange Code refers to a large collection of slightly different single and multi byte coded character sets that are different from ASCII or ISO 8859-1 and typically run on host computers. The EBCDIC encodings derive from 8 bit byte extensions of Hollerith punched card encodings.The layout on the cards was such that high bits were set for theupper and lower case alphabet characters [a-z] and [A-Z], but therewere gaps within each latin alphabet range.Some IBM EBCDIC character sets may be known by character code set identification numbers (CCSID numbers) or code page numbers. Leadingzero digits in CCSID numbers within this document are insignificant.E.g. CCSID 0037 may be referred to as 37 in places.=head2 13 variant charactersAmong IBM EBCDIC character code sets there are 13 characters thatare often mapped to different integer values. Those charactersare known as the 13 "variant" characters and are: \ [ ] { } ^ ~ ! # | $ @ ` =head2 0037Character code set ID 0037 is a mapping of the ASCII plus Latin-1 characters (i.e. ISO 8859-1) to an EBCDIC set. 0037 is used in North American English locales on the OS/400 operating system that runs on AS/400 computers. CCSID 37 differs from ISO 8859-1 in 237 places, in other words they agree on only 19 code point values.=head2 1047Character code set ID 1047 is also a mapping of the ASCII plus Latin-1 characters (i.e. ISO 8859-1) to an EBCDIC set. 1047 is used under Unix System Services for OS/390 or z/OS, and OpenEdition for VM/ESA. CCSID 1047 differs from CCSID 0037 in eight places.=head2 POSIX-BCThe EBCDIC code page in use on Siemens' BS2000 system is distinct from1047 and 0037. It is identified below as the POSIX-BC set.=head2 Unicode code points versus EBCDIC code pointsIn Unicode terminology a I<code point> is the number assigned to acharacter: for example, in EBCDIC the character "A" is usually assignedthe number 193. In Unicode the character "A" is assigned the number 65.This causes a problem with the semantics of the pack/unpack "U", whichare supposed to pack Unicode code points to characters and back to numbers.The problem is: which code points to use for code points less than 256?(for 256 and over there's no problem: Unicode code points are used)In EBCDIC, for the low 256 the EBCDIC code points are used. Thismeans that the equivalences pack("U", ord($character)) eq $character unpack("U", $character) == ord $characterwill hold. (If Unicode code points were applied consistently overall the possible code points, pack("U",ord("A")) would in EBCDICequal I<A with acute> or chr(101), and unpack("U", "A") would equal65, or I<non-breaking space>, not 193, or ord "A".)=head2 Remaining Perl Unicode problems in EBCDIC=over 4=item *Many of the remaining seem to be related to case-insensitive matching:for example, C<< /[\x{131}]/ >> (LATIN SMALL LETTER DOTLESS I) doesnot match "I" case-insensitively, as it should under Unicode.(The match succeeds in ASCII-derived platforms.)=item *The extensions Unicode::Collate and Unicode::Normalized are notsupported under EBCDIC, likewise for the encoding pragma.=back=head2 Unicode and UTFUTF is a Unicode Transformation Format. UTF-8 is a Unicode conformingrepresentation of the Unicode standard that looks very much like ASCII.UTF-EBCDIC is an attempt to represent Unicode characters in an EBCDICtransparent manner.=head2 Using EncodeStarting from Perl 5.8 you can use the standard new module Encodeto translate from EBCDIC to Latin-1 code points 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 pointsand from Latin-1 code points to EBCDIC code points 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 pointsFor doing I/O it is suggested that you use the autotranslating featuresof PerlIO, see L<perluniintro>.Since version 5.8 Perl uses the new PerlIO I/O library. This enablesyou to use different encodings per IO channel. For example you may use 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";to get two files containing "Hello World!\n" in ASCII, CP 37 EBCDIC,ISO 8859-1 (Latin-1) (in this example identical to ASCII) respectiveUTF-EBCDIC (in this example identical to normal EBCDIC). See thedocumentation of Encode::PerlIO for details.As the PerlIO layer uses raw IO (bytes) internally, all this totallyignores things like the type of your filesystem (ASCII or EBCDIC).=head1 SINGLE OCTET TABLESThe following tables list the ASCII and Latin 1 ordered sets includingthe subsets: C0 controls (0..31), ASCII graphics (32..7e), delete (7f),C1 controls (80..9f), and Latin-1 (a.k.a. ISO 8859-1) (a0..ff). In the table non-printing control character names as well as the Latin 1 extensions to ASCII have been labelled with character names roughly corresponding to I<The Unicode Standard, Version 3.0> albeit with substitutions such as s/LATIN// and s/VULGAR// in all cases, s/CAPITAL LETTER// in some cases, and s/SMALL LETTER ([A-Z])/\l$1/ in some other cases (the C<charnames> pragma names unfortunately do not list explicit names for the C0 or C1 control characters). The "names" of the C1 control set (128..159 in ISO 8859-1) listed here are somewhat arbitrary. The differences between the 0037 and 1047 sets are flagged with ***. The differences between the 1047 and POSIX-BC sets are flagged with ###. All ord() numbers listed are decimal. If you would rather see this table listing octal values then run the table (that is, the pod version of this document since this recipe may not work with a pod2_other_format translation) through:=over 4=item recipe 0=back perl -ne 'if(/(.{33})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/)' \ -e '{printf("%s%-9o%-9o%-9o%o\n",$1,$2,$3,$4,$5)}' perlebcdic.podIf you want to retain the UTF-x code points then in script form youmight want to write:=over 4=item recipe 1=back open(FH,"<perlebcdic.pod") or die "Could not open perlebcdic.pod: $!"; while (<FH>) { if (/(.{33})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\.?(\d*)\s+(\d+)\.?(\d*)/) { if ($7 ne '' && $9 ne '') { printf("%s%-9o%-9o%-9o%-9o%-3o.%-5o%-3o.%o\n",$1,$2,$3,$4,$5,$6,$7,$8,$9); } elsif ($7 ne '') { printf("%s%-9o%-9o%-9o%-9o%-3o.%-5o%o\n",$1,$2,$3,$4,$5,$6,$7,$8); } else { printf("%s%-9o%-9o%-9o%-9o%-9o%o\n",$1,$2,$3,$4,$5,$6,$8); } } }If you would rather see this table listing hexadecimal values then
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -