perlebcdic.html

来自「perl教程」· HTML 代码 · 共 806 行 · 第 1/5 页

HTML
806
字号
upper and lower case alphabet characters [a-z] and [A-Z], but there
were gaps within each latin alphabet range.</p>
<p>Some IBM EBCDIC character sets may be known by character code set 
identification numbers (CCSID numbers) or code page numbers.  Leading
zero digits in CCSID numbers within this document are insignificant.
E.g. CCSID 0037 may be referred to as 37 in places.</p>
<p>
</p>
<h2><a name="13_variant_characters">13 variant characters</a></h2>
<p>Among IBM EBCDIC character code sets there are 13 characters that
are often mapped to different integer values.  Those characters
are known as the 13 &quot;variant&quot; characters and are:</p>
<pre>
    <span class="operator">\</span> <span class="operator">[</span> <span class="operator">]</span> <span class="operator">{</span> <span class="operator">}</span> <span class="operator">^</span> <span class="operator">~</span> <span class="operator">!</span> <span class="comment"># | $ @ `</span>
</pre>
<p>
</p>
<h2><a name="0037">0037</a></h2>
<p>Character 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.</p>
<p>
</p>
<h2><a name="1047">1047</a></h2>
<p>Character 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.</p>
<p>
</p>
<h2><a name="posixbc">POSIX-BC</a></h2>
<p>The EBCDIC code page in use on Siemens' BS2000 system is distinct from
1047 and 0037.  It is identified below as the POSIX-BC set.</p>
<p>
</p>
<h2><a name="unicode_code_points_versus_ebcdic_code_points">Unicode code points versus EBCDIC code points</a></h2>
<p>In Unicode terminology a <em>code point</em> is the number assigned to a
character: for example, in EBCDIC the character &quot;A&quot; is usually assigned
the number 193.  In Unicode the character &quot;A&quot; is assigned the number 65.
This causes a problem with the semantics of the pack/unpack &quot;U&quot;, which
are 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.  This
means that the equivalences</p>
<pre>
        pack(&quot;U&quot;, ord($character)) eq $character
        unpack(&quot;U&quot;, $character) == ord $character</pre>
<p>will hold.  (If Unicode code points were applied consistently over
all the possible code points, <a href="#item_pack"><code>pack(&quot;U&quot;,ord(&quot;A&quot;))</code></a> would in EBCDIC
equal <em>A with acute</em> or chr(101), and unpack(&quot;U&quot;, &quot;A&quot;) would equal
65, or <em>non-breaking space</em>, not 193, or ord &quot;A&quot;.)</p>
<p>
</p>
<h2><a name="remaining_perl_unicode_problems_in_ebcdic">Remaining Perl Unicode problems in EBCDIC</a></h2>
<ul>
<li>
<p>Many of the remaining seem to be related to case-insensitive matching:
for example, <code>/[\x{131}]/</code> (LATIN SMALL LETTER DOTLESS I) does
not match &quot;I&quot; case-insensitively, as it should under Unicode.
(The match succeeds in ASCII-derived platforms.)</p>
</li>
<li>
<p>The extensions Unicode::Collate and Unicode::Normalized are not
supported under EBCDIC, likewise for the encoding pragma.</p>
</li>
</ul>
<p>
</p>
<h2><a name="unicode_and_utf">Unicode and UTF</a></h2>
<p>UTF is a Unicode Transformation Format.  UTF-8 is a Unicode conforming
representation of the Unicode standard that looks very much like ASCII.
UTF-EBCDIC is an attempt to represent Unicode characters in an EBCDIC
transparent manner.</p>
<p>
</p>
<h2><a name="using_encode">Using Encode</a></h2>
<p>Starting from Perl 5.8 you can use the standard new module Encode
to translate from EBCDIC to Latin-1 code points</p>
<pre>
        <span class="keyword">use</span> <span class="variable">Encode</span> <span class="string">'from_to'</span><span class="operator">;</span>
</pre>
<pre>
        <span class="keyword">my</span> <span class="variable">%ebcdic</span> <span class="operator">=</span> <span class="operator">(</span> <span class="number">176</span> <span class="operator">=&gt;</span> <span class="string">'cp37'</span><span class="operator">,</span> <span class="number">95</span> <span class="operator">=&gt;</span> <span class="string">'cp1047'</span><span class="operator">,</span> <span class="number">106</span> <span class="operator">=&gt;</span> <span class="string">'posix-bc'</span> <span class="operator">);</span>
</pre>
<pre>
        <span class="comment"># $a is in EBCDIC code points</span>
        <span class="variable">from_to</span><span class="operator">(</span><span class="variable">$a</span><span class="operator">,</span> <span class="variable">$ebcdic</span><span class="operator">{</span><span class="keyword">ord</span> <span class="string">'^'</span><span class="operator">}</span><span class="operator">,</span> <span class="string">'latin1'</span><span class="operator">);</span>
        <span class="comment"># $a is ISO 8859-1 code points</span>
</pre>
<p>and from Latin-1 code points to EBCDIC code points</p>
<pre>
        <span class="keyword">use</span> <span class="variable">Encode</span> <span class="string">'from_to'</span><span class="operator">;</span>
</pre>
<pre>
        <span class="keyword">my</span> <span class="variable">%ebcdic</span> <span class="operator">=</span> <span class="operator">(</span> <span class="number">176</span> <span class="operator">=&gt;</span> <span class="string">'cp37'</span><span class="operator">,</span> <span class="number">95</span> <span class="operator">=&gt;</span> <span class="string">'cp1047'</span><span class="operator">,</span> <span class="number">106</span> <span class="operator">=&gt;</span> <span class="string">'posix-bc'</span> <span class="operator">);</span>
</pre>
<pre>
        <span class="comment"># $a is ISO 8859-1 code points</span>
        <span class="variable">from_to</span><span class="operator">(</span><span class="variable">$a</span><span class="operator">,</span> <span class="string">'latin1'</span><span class="operator">,</span> <span class="variable">$ebcdic</span><span class="operator">{</span><span class="keyword">ord</span> <span class="string">'^'</span><span class="operator">}</span><span class="operator">);</span>
        <span class="comment"># $a is in EBCDIC code points</span>
</pre>
<p>For doing I/O it is suggested that you use the autotranslating features
of PerlIO, see <a href="../../lib/Pod/perluniintro.html">the perluniintro manpage</a>.</p>
<p>Since version 5.8 Perl uses the new PerlIO I/O library.  This enables
you to use different encodings per IO channel.  For example you may use</p>
<pre>
    <span class="keyword">use</span> <span class="variable">Encode</span><span class="operator">;</span>
    <span class="keyword">open</span><span class="operator">(</span><span class="variable">$f</span><span class="operator">,</span> <span class="string">"&gt;:encoding(ascii)"</span><span class="operator">,</span> <span class="string">"test.ascii"</span><span class="operator">);</span>
    <span class="keyword">print</span> <span class="variable">$f</span> <span class="string">"Hello World!\n"</span><span class="operator">;</span>
    <span class="keyword">open</span><span class="operator">(</span><span class="variable">$f</span><span class="operator">,</span> <span class="string">"&gt;:encoding(cp37)"</span><span class="operator">,</span> <span class="string">"test.ebcdic"</span><span class="operator">);</span>
    <span class="keyword">print</span> <span class="variable">$f</span> <span class="string">"Hello World!\n"</span><span class="operator">;</span>
    <span class="keyword">open</span><span class="operator">(</span><span class="variable">$f</span><span class="operator">,</span> <span class="string">"&gt;:encoding(latin1)"</span><span class="operator">,</span> <span class="string">"test.latin1"</span><span class="operator">);</span>
    <span class="keyword">print</span> <span class="variable">$f</span> <span class="string">"Hello World!\n"</span><span class="operator">;</span>
    <span class="keyword">open</span><span class="operator">(</span><span class="variable">$f</span><span class="operator">,</span> <span class="string">"&gt;:encoding(utf8)"</span><span class="operator">,</span> <span class="string">"test.utf8"</span><span class="operator">);</span>
    <span class="keyword">print</span> <span class="variable">$f</span> <span class="string">"Hello World!\n"</span><span class="operator">;</span>
</pre>
<p>to get two files containing &quot;Hello World!\n&quot; in ASCII, CP 37 EBCDIC,
ISO 8859-1 (Latin-1) (in this example identical to ASCII) respective
UTF-EBCDIC (in this example identical to normal EBCDIC).  See the
documentation of Encode::PerlIO for details.</p>
<p>As the PerlIO layer uses raw IO (bytes) internally, all this totally
ignores things like the type of your filesystem (ASCII or EBCDIC).</p>
<p>
</p>
<hr />
<h1><a name="single_octet_tables">SINGLE OCTET TABLES</a></h1>
<p>The following tables list the ASCII and Latin 1 ordered sets including
the 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 <em>The Unicode Standard, Version 3.0</em> 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 <code>charnames</code> pragma names unfortunately do 
not list explicit names for the C0 or C1 control characters).  The 
&quot;names&quot; 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 <a href="#item_ord"><code>ord()</code></a> 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:</p>
<dl>
<dt><strong><a name="item_recipe_0">recipe 0</a></strong>

</dl>
<pre>
    <span class="variable">perl</span> <span class="operator">-</span><span class="keyword">ne</span> <span class="string">'if(/(.{33})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/)'</span> <span class="operator">\</span>
     <span class="keyword">-e</span> <span class="string">'{printf("%s%-9o%-9o%-9o%o\n",$1,$2,$3,$4,$5)}'</span> <span class="variable">perlebcdic</span><span class="operator">.</span><span class="variable">pod</span>
</pre>
<p>If you want to retain the UTF-x code points then in script form you
might want to write:</p>
<dl>
<dt><strong><a name="item_recipe_1">recipe 1</a></strong>

</dl>
<pre>
    <span class="keyword">open</span><span class="operator">(</span><span class="variable">FH</span><span class="operator">,</span><span class="string">"&lt;perlebcdic.pod"</span><span class="operator">)</span> <span class="keyword">or</span> <span class="keyword">die</span> <span class="string">"Could not open perlebcdic.pod: $!"</span><span class="operator">;</span>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?