home *** CD-ROM | disk | FTP | other *** search
/ Australian Personal Computer 2004 July / APC0407D2.iso / workshop / apache / files / ActivePerl-5.6.1.638-MSWin32-x86.msi / _49d4bd2772336d3138aa1343bceae5b5 < prev    next >
Encoding:
Text File  |  2004-04-13  |  54.1 KB  |  1,236 lines

  1. =head1 NAME
  2.  
  3. perlebcdic - Considerations for running Perl on EBCDIC platforms
  4.  
  5. =head1 DESCRIPTION
  6.  
  7. An exploration of some of the issues facing Perl programmers
  8. on EBCDIC based computers.  We do not cover localization, 
  9. internationalization, or multi byte character set issues (yet).
  10.  
  11. Portions that are still incomplete are marked with XXX.
  12.  
  13. =head1 COMMON CHARACTER CODE SETS
  14.  
  15. =head2 ASCII
  16.  
  17. The American Standard Code for Information Interchange is a set of
  18. integers running from 0 to 127 (decimal) that imply character 
  19. interpretation by the display and other system(s) of computers.  
  20. The range 0..127 can be covered by setting the bits in a 7-bit binary 
  21. digit, hence the set is sometimes referred to as a "7-bit ASCII".  
  22. ASCII was described by the American National Standards Institute 
  23. document ANSI X3.4-1986.  It was also described by ISO 646:1991 
  24. (with localization for currency symbols).  The full ASCII set is 
  25. given in the table below as the first 128 elements.  Languages that 
  26. can be written adequately with the characters in ASCII include 
  27. English, Hawaiian, Indonesian, Swahili and some Native American 
  28. languages.
  29.  
  30. There are many character sets that extend the range of integers
  31. from 0..2**7-1 up to 2**8-1, or 8 bit bytes (octets if you prefer).
  32. One common one is the ISO 8859-1 character set.
  33.  
  34. =head2 ISO 8859
  35.  
  36. The ISO 8859-$n are a collection of character code sets from the 
  37. International Organization for Standardization (ISO) each of which 
  38. adds characters to the ASCII set that are typically found in European 
  39. languages many of which are based on the Roman, or Latin, alphabet.
  40.  
  41. =head2 Latin 1 (ISO 8859-1)
  42.  
  43. A particular 8-bit extension to ASCII that includes grave and acute 
  44. accented Latin characters.  Languages that can employ ISO 8859-1 
  45. include all the languages covered by ASCII as well as Afrikaans, 
  46. Albanian, Basque, Catalan, Danish, Faroese, Finnish, Norwegian, 
  47. Portugese, Spanish, and Swedish.  Dutch is covered albeit without 
  48. the ij ligature.  French is covered too but without the oe ligature. 
  49. German can use ISO 8859-1 but must do so without German-style
  50. quotation marks.  This set is based on Western European extensions 
  51. to ASCII and is commonly encountered in world wide web work.
  52. In IBM character code set identification terminology ISO 8859-1 is
  53. also known as CCSID 819 (or sometimes 0819 or even 00819).
  54.  
  55. =head2 EBCDIC
  56.  
  57. The Extended Binary Coded Decimal Interchange Code  refers to a 
  58. large collection of slightly different single and multi byte 
  59. coded character sets that are different from ASCII or ISO 8859-1 
  60. and typically run on host computers.  The EBCDIC encodings derive 
  61. from 8 bit byte extensions of Hollerith punched card encodings.
  62. The layout on the cards was such that high bits were set for the
  63. upper and lower case alphabet characters [a-z] and [A-Z], but there
  64. were gaps within each latin alphabet range.
  65.  
  66. Some IBM EBCDIC character sets may be known by character code set 
  67. identification numbers (CCSID numbers) or code page numbers.  Leading
  68. zero digits in CCSID numbers within this document are insignificant.
  69. E.g. CCSID 0037 may be referred to as 37 in places.
  70.  
  71. =head2 13 variant characters
  72.  
  73. Among IBM EBCDIC character code sets there are 13 characters that
  74. are often mapped to different integer values.  Those characters
  75. are known as the 13 "variant" characters and are:
  76.  
  77.     \ [ ] { } ^ ~ ! # | $ @ ` 
  78.  
  79. =head2 0037
  80.  
  81. Character code set ID 0037 is a mapping of the ASCII plus Latin-1 
  82. characters (i.e. ISO 8859-1) to an EBCDIC set.  0037 is used 
  83. in North American English locales on the OS/400 operating system 
  84. that runs on AS/400 computers.  CCSID 37 differs from ISO 8859-1 
  85. in 237 places, in other words they agree on only 19 code point values.
  86.  
  87. =head2 1047
  88.  
  89. Character code set ID 1047 is also a mapping of the ASCII plus 
  90. Latin-1 characters (i.e. ISO 8859-1) to an EBCDIC set.  1047 is 
  91. used under Unix System Services for OS/390, and OpenEdition for VM/ESA. 
  92. CCSID 1047 differs from CCSID 0037 in eight places.
  93.  
  94. =head2 POSIX-BC
  95.  
  96. The EBCDIC code page in use on Siemens' BS2000 system is distinct from
  97. 1047 and 0037.  It is identified below as the POSIX-BC set.
  98.  
  99. =head1 SINGLE OCTET TABLES
  100.  
  101. The following tables list the ASCII and Latin 1 ordered sets including
  102. the subsets: C0 controls (0..31), ASCII graphics (32..7e), delete (7f),
  103. C1 controls (80..9f), and Latin-1 (a.k.a. ISO 8859-1) (a0..ff).  In the 
  104. table non-printing control character names as well as the Latin 1 
  105. extensions to ASCII have been labelled with character names roughly 
  106. corresponding to I<The Unicode Standard, Version 2.0> albeit with 
  107. substitutions such as s/LATIN// and s/VULGAR// in all cases, 
  108. s/CAPITAL LETTER// in some cases, and s/SMALL LETTER ([A-Z])/\l$1/ 
  109. in some other cases (the C<charnames> pragma names unfortunately do 
  110. not list explicit names for the C0 or C1 control characters).  The 
  111. "names" of the C1 control set (128..159 in ISO 8859-1) listed here are 
  112. somewhat arbitrary.  The differences between the 0037 and 1047 sets are 
  113. flagged with ***.  The differences between the 1047 and POSIX-BC sets 
  114. are flagged with ###.  All ord() numbers listed are decimal.  If you 
  115. would rather see this table listing octal values then run the table 
  116. (that is, the pod version of this document since this recipe may not 
  117. work with a pod2_other_format translation) through:
  118.  
  119. =over 4
  120.  
  121. =item recipe 0
  122.  
  123. =back
  124.  
  125.     perl -ne 'if(/(.{33})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/)' \
  126.      -e '{printf("%s%-9o%-9o%-9o%-9o\n",$1,$2,$3,$4,$5)}' perlebcdic.pod
  127.  
  128. If you would rather see this table listing hexadecimal values then
  129. run the table through:
  130.  
  131. =over 4
  132.  
  133. =item recipe 1
  134.  
  135. =back
  136.  
  137.     perl -ne 'if(/(.{33})(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/)' \
  138.      -e '{printf("%s%-9X%-9X%-9X%-9X\n",$1,$2,$3,$4,$5)}' perlebcdic.pod
  139.  
  140.  
  141.                                  8859-1
  142.     chr                          0819     0037     1047     POSIX-BC
  143.     ----------------------------------------------------------------
  144.     <NULL>                       0        0        0        0 
  145.     <START OF HEADING>           1        1        1        1
  146.     <START OF TEXT>              2        2        2        2
  147.     <END OF TEXT>                3        3        3        3
  148.     <END OF TRANSMISSION>        4        55       55       55
  149.     <ENQUIRY>                    5        45       45       45
  150.     <ACKNOWLEDGE>                6        46       46       46
  151.     <BELL>                       7        47       47       47
  152.     <BACKSPACE>                  8        22       22       22
  153.     <HORIZONTAL TABULATION>      9        5        5        5
  154.     <LINE FEED>                  10       37       21       21  ***
  155.     <VERTICAL TABULATION>        11       11       11       11
  156.     <FORM FEED>                  12       12       12       12
  157.     <CARRIAGE RETURN>            13       13       13       13
  158.     <SHIFT OUT>                  14       14       14       14
  159.     <SHIFT IN>                   15       15       15       15
  160.     <DATA LINK ESCAPE>           16       16       16       16
  161.     <DEVICE CONTROL ONE>         17       17       17       17
  162.     <DEVICE CONTROL TWO>         18       18       18       18
  163.     <DEVICE CONTROL THREE>       19       19       19       19
  164.     <DEVICE CONTROL FOUR>        20       60       60       60
  165.     <NEGATIVE ACKNOWLEDGE>       21       61       61       61
  166.     <SYNCHRONOUS IDLE>           22       50       50       50
  167.     <END OF TRANSMISSION BLOCK>  23       38       38       38
  168.     <CANCEL>                     24       24       24       24
  169.     <END OF MEDIUM>              25       25       25       25
  170.     <SUBSTITUTE>                 26       63       63       63
  171.     <ESCAPE>                     27       39       39       39
  172.     <FILE SEPARATOR>             28       28       28       28
  173.     <GROUP SEPARATOR>            29       29       29       29
  174.     <RECORD SEPARATOR>           30       30       30       30
  175.     <UNIT SEPARATOR>             31       31       31       31
  176.     <SPACE>                      32       64       64       64
  177.     !                            33       90       90       90
  178.     "                            34       127      127      127
  179.     #                            35       123      123      123
  180.     $                            36       91       91       91
  181.     %                            37       108      108      108
  182.     &                            38       80       80       80
  183.     '                            39       125      125      125
  184.     (                            40       77       77       77
  185.     )                            41       93       93       93
  186.     *                            42       92       92       92
  187.     +                            43       78       78       78
  188.     ,                            44       107      107      107
  189.     -                            45       96       96       96
  190.     .                            46       75       75       75
  191.     /                            47       97       97       97
  192.     0                            48       240      240      240
  193.     1                            49       241      241      241
  194.     2                            50       242      242      242
  195.     3                            51       243      243      243
  196.     4                            52       244      244      244
  197.     5                            53       245      245      245
  198.     6                            54       246      246      246
  199.     7                            55       247      247      247
  200.     8                            56       248      248      248
  201.     9                            57       249      249      249
  202.     :                            58       122      122      122
  203.     ;                            59       94       94       94
  204.     <                            60       76       76       76
  205.     =                            61       126      126      126
  206.     >                            62       110      110      110
  207.     ?                            63       111      111      111
  208.     @                            64       124      124      124
  209.     A                            65       193      193      193
  210.     B                            66       194      194      194
  211.     C                            67       195      195      195
  212.     D                            68       196      196      196
  213.     E                            69       197      197      197
  214.     F                            70       198      198      198
  215.     G                            71       199      199      199
  216.     H                            72       200      200      200
  217.     I                            73       201      201      201
  218.     J                            74       209      209      209
  219.     K                            75       210      210      210
  220.     L                            76       211      211      211
  221.     M                            77       212      212      212
  222.     N                            78       213      213      213
  223.     O                            79       214      214      214
  224.     P                            80       215      215      215
  225.     Q                            81       216      216      216
  226.     R                            82       217      217      217
  227.     S                            83       226      226      226
  228.     T                            84       227      227      227
  229.     U                            85       228      228      228
  230.     V                            86       229      229      229
  231.     W                            87       230      230      230
  232.     X                            88       231      231      231
  233.     Y                            89       232      232      232
  234.     Z                            90       233      233      233
  235.     [                            91       186      173      187 *** ###
  236.     \                            92       224      224      188 ### 
  237.     ]                            93       187      189      189 ***
  238.     ^                            94       176      95       106 *** ###
  239.     _                            95       109      109      109
  240.     `                            96       121      121      74  ###
  241.     a                            97       129      129      129
  242.     b                            98       130      130      130
  243.     c                            99       131      131      131
  244.     d                            100      132      132      132
  245.     e                            101      133      133      133
  246.     f                            102      134      134      134
  247.     g                            103      135      135      135
  248.     h                            104      136      136      136
  249.     i                            105      137      137      137
  250.     j                            106      145      145      145
  251.     k                            107      146      146      146
  252.     l                            108      147      147      147
  253.     m                            109      148      148      148
  254.     n                            110      149      149      149
  255.     o                            111      150      150      150
  256.     p                            112      151      151      151
  257.     q                            113      152      152      152
  258.     r                            114      153      153      153
  259.     s                            115      162      162      162
  260.     t                            116      163      163      163
  261.     u                            117      164      164      164
  262.     v                            118      165      165      165
  263.     w                            119      166      166      166
  264.     x                            120      167      167      167
  265.     y                            121      168      168      168
  266.     z                            122      169      169      169
  267.     {                            123      192      192      251 ###
  268.     |                            124      79       79       79
  269.     }                            125      208      208      253 ###
  270.     ~                            126      161      161      255 ###
  271.     <DELETE>                     127      7        7        7
  272.     <C1 0>                       128      32       32       32
  273.     <C1 1>                       129      33       33       33
  274.     <C1 2>                       130      34       34       34
  275.     <C1 3>                       131      35       35       35
  276.     <C1 4>                       132      36       36       36
  277.     <C1 5>                       133      21       37       37  ***
  278.     <C1 6>                       134      6        6        6
  279.     <C1 7>                       135      23       23       23
  280.     <C1 8>                       136      40       40       40
  281.     <C1 9>                       137      41       41       41
  282.     <C1 10>                      138      42       42       42
  283.     <C1 11>                      139      43       43       43
  284.     <C1 12>                      140      44       44       44
  285.     <C1 13>                      141      9        9        9
  286.     <C1 14>                      142      10       10       10
  287.     <C1 15>                      143      27       27       27
  288.     <C1 16>                      144      48       48       48
  289.     <C1 17>                      145      49       49       49
  290.     <C1 18>                      146      26       26       26
  291.     <C1 19>                      147      51       51       51
  292.     <C1 20>                      148      52       52       52
  293.     <C1 21>                      149      53       53       53
  294.     <C1 22>                      150      54       54       54
  295.     <C1 23>                      151      8        8        8
  296.     <C1 24>                      152      56       56       56
  297.     <C1 25>                      153      57       57       57
  298.     <C1 26>                      154      58       58       58
  299.     <C1 27>                      155      59       59       59
  300.     <C1 28>                      156      4        4        4
  301.     <C1 29>                      157      20       20       20
  302.     <C1 30>                      158      62       62       62
  303.     <C1 31>                      159      255      255      95  ###
  304.     <NON-BREAKING SPACE>         160      65       65       65
  305.     <INVERTED EXCLAMATION MARK>  161      170      170      170
  306.     <CENT SIGN>                  162      74       74       176 ###
  307.     <POUND SIGN>                 163      177      177      177
  308.     <CURRENCY SIGN>              164      159      159      159
  309.     <YEN SIGN>                   165      178      178      178
  310.     <BROKEN BAR>                 166      106      106      208 ###
  311.     <SECTION SIGN>               167      181      181      181
  312.     <DIAERESIS>                  168      189      187      121 *** ###
  313.     <COPYRIGHT SIGN>             169      180      180      180
  314.     <FEMININE ORDINAL INDICATOR> 170      154      154      154
  315.     <LEFT POINTING GUILLEMET>    171      138      138      138
  316.     <NOT SIGN>                   172      95       176      186 *** ###       
  317.     <SOFT HYPHEN>                173      202      202      202
  318.     <REGISTERED TRADE MARK SIGN> 174      175      175      175
  319.     <MACRON>                     175      188      188      161 ###
  320.     <DEGREE SIGN>                176      144      144      144
  321.     <PLUS-OR-MINUS SIGN>         177      143      143      143
  322.     <SUPERSCRIPT TWO>            178      234      234      234
  323.     <SUPERSCRIPT THREE>          179      250      250      250
  324.     <ACUTE ACCENT>               180      190      190      190
  325.     <MICRO SIGN>                 181      160      160      160
  326.     <PARAGRAPH SIGN>             182      182      182      182
  327.     <MIDDLE DOT>                 183      179      179      179
  328.     <CEDILLA>                    184      157      157      157
  329.     <SUPERSCRIPT ONE>            185      218      218      218
  330.     <MASC. ORDINAL INDICATOR>    186      155      155      155
  331.     <RIGHT POINTING GUILLEMET>   187      139      139      139
  332.     <FRACTION ONE QUARTER>       188      183      183      183
  333.     <FRACTION ONE HALF>          189      184      184      184
  334.     <FRACTION THREE QUARTERS>    190      185      185      185
  335.     <INVERTED QUESTION MARK>     191      171      171      171
  336.     <A WITH GRAVE>               192      100      100      100
  337.     <A WITH ACUTE>               193      101      101      101
  338.     <A WITH CIRCUMFLEX>          194      98       98       98
  339.     <A WITH TILDE>               195      102      102      102
  340.     <A WITH DIAERESIS>           196      99       99       99
  341.     <A WITH RING ABOVE>          197      103      103      103
  342.     <CAPITAL LIGATURE AE>        198      158      158      158
  343.     <C WITH CEDILLA>             199      104      104      104
  344.     <E WITH GRAVE>               200      116      116      116
  345.     <E WITH ACUTE>               201      113      113      113
  346.     <E WITH CIRCUMFLEX>          202      114      114      114
  347.     <E WITH DIAERESIS>           203      115      115      115
  348.     <I WITH GRAVE>               204      120      120      120
  349.     <I WITH ACUTE>               205      117      117      117
  350.     <I WITH CIRCUMFLEX>          206      118      118      118
  351.     <I WITH DIAERESIS>           207      119      119      119
  352.     <CAPITAL LETTER ETH>         208      172      172      172
  353.     <N WITH TILDE>               209      105      105      105
  354.     <O WITH GRAVE>               210      237      237      237
  355.     <O WITH ACUTE>               211      238      238      238
  356.     <O WITH CIRCUMFLEX>          212      235      235      235
  357.     <O WITH TILDE>               213      239      239      239
  358.     <O WITH DIAERESIS>           214      236      236      236
  359.     <MULTIPLICATION SIGN>        215      191      191      191
  360.     <O WITH STROKE>              216      128      128      128
  361.     <U WITH GRAVE>               217      253      253      224 ###
  362.     <U WITH ACUTE>               218      254      254      254
  363.     <U WITH CIRCUMFLEX>          219      251      251      221 ###
  364.     <U WITH DIAERESIS>           220      252      252      252
  365.     <Y WITH ACUTE>               221      173      186      173 *** ###
  366.     <CAPITAL LETTER THORN>       222      174      174      174
  367.     <SMALL LETTER SHARP S>       223      89       89       89
  368.     <a WITH GRAVE>               224      68       68       68
  369.     <a WITH ACUTE>               225      69       69       69
  370.     <a WITH CIRCUMFLEX>          226      66       66       66
  371.     <a WITH TILDE>               227      70       70       70
  372.     <a WITH DIAERESIS>           228      67       67       67
  373.     <a WITH RING ABOVE>          229      71       71       71
  374.     <SMALL LIGATURE ae>          230      156      156      156
  375.     <c WITH CEDILLA>             231      72       72       72
  376.     <e WITH GRAVE>               232      84       84       84
  377.     <e WITH ACUTE>               233      81       81       81
  378.     <e WITH CIRCUMFLEX>          234      82       82       82
  379.     <e WITH DIAERESIS>           235      83       83       83
  380.     <i WITH GRAVE>               236      88       88       88
  381.     <i WITH ACUTE>               237      85       85       85
  382.     <i WITH CIRCUMFLEX>          238      86       86       86
  383.     <i WITH DIAERESIS>           239      87       87       87
  384.     <SMALL LETTER eth>           240      140      140      140
  385.     <n WITH TILDE>               241      73       73       73
  386.     <o WITH GRAVE>               242      205      205      205
  387.     <o WITH ACUTE>               243      206      206      206
  388.     <o WITH CIRCUMFLEX>          244      203      203      203
  389.     <o WITH TILDE>               245      207      207      207
  390.     <o WITH DIAERESIS>           246      204      204      204
  391.     <DIVISION SIGN>              247      225      225      225
  392.     <o WITH STROKE>              248      112      112      112
  393.     <u WITH GRAVE>               249      221      221      192 ###
  394.     <u WITH ACUTE>               250      222      222      222
  395.     <u WITH CIRCUMFLEX>          251      219      219      219
  396.     <u WITH DIAERESIS>           252      220      220      220
  397.     <y WITH ACUTE>               253      141      141      141
  398.     <SMALL LETTER thorn>         254      142      142      142
  399.     <y WITH DIAERESIS>           255      223      223      223
  400.  
  401. If you would rather see the above table in CCSID 0037 order rather than
  402. ASCII + Latin-1 order then run the table through:
  403.  
  404. =over 4
  405.  
  406. =item recipe 2
  407.  
  408. =back
  409.  
  410.     perl -ne 'if(/.{33}\d{1,3}\s{6,8}\d{1,3}\s{6,8}\d{1,3}\s{6,8}\d{1,3}/)'\
  411.      -e '{push(@l,$_)}' \
  412.      -e 'END{print map{$_->[0]}' \
  413.      -e '          sort{$a->[1] <=> $b->[1]}' \ 
  414.      -e '          map{[$_,substr($_,42,3)]}@l;}' perlebcdic.pod
  415.  
  416. If you would rather see it in CCSID 1047 order then change the digit
  417. 42 in the last line to 51, like this:
  418.  
  419. =over 4
  420.  
  421. =item recipe 3
  422.  
  423. =back
  424.  
  425.     perl -ne 'if(/.{33}\d{1,3}\s{6,8}\d{1,3}\s{6,8}\d{1,3}\s{6,8}\d{1,3}/)'\
  426.      -e '{push(@l,$_)}' \
  427.      -e 'END{print map{$_->[0]}' \
  428.      -e '          sort{$a->[1] <=> $b->[1]}' \ 
  429.      -e '          map{[$_,substr($_,51,3)]}@l;}' perlebcdic.pod
  430.  
  431. If you would rather see it in POSIX-BC order then change the digit
  432. 51 in the last line to 60, like this:
  433.  
  434. =over 4
  435.  
  436. =item recipe 4
  437.  
  438. =back
  439.  
  440.     perl -ne 'if(/.{33}\d{1,3}\s{6,8}\d{1,3}\s{6,8}\d{1,3}\s{6,8}\d{1,3}/)'\
  441.      -e '{push(@l,$_)}' \
  442.      -e 'END{print map{$_->[0]}' \
  443.      -e '          sort{$a->[1] <=> $b->[1]}' \ 
  444.      -e '          map{[$_,substr($_,60,3)]}@l;}' perlebcdic.pod
  445.  
  446.  
  447. =head1 IDENTIFYING CHARACTER CODE SETS
  448.  
  449. To determine the character set you are running under from perl one 
  450. could use the return value of ord() or chr() to test one or more 
  451. character values.  For example:
  452.  
  453.     $is_ascii  = "A" eq chr(65);
  454.     $is_ebcdic = "A" eq chr(193);
  455.  
  456. Also, "\t" is a C<HORIZONTAL TABULATION> character so that:
  457.  
  458.     $is_ascii  = ord("\t") == 9;
  459.     $is_ebcdic = ord("\t") == 5;
  460.  
  461. To distinguish EBCDIC code pages try looking at one or more of
  462. the characters that differ between them.  For example:
  463.  
  464.     $is_ebcdic_37   = "\n" eq chr(37);
  465.     $is_ebcdic_1047 = "\n" eq chr(21);
  466.  
  467. Or better still choose a character that is uniquely encoded in any
  468. of the code sets, e.g.:
  469.  
  470.     $is_ascii           = ord('[') == 91;
  471.     $is_ebcdic_37       = ord('[') == 186;
  472.     $is_ebcdic_1047     = ord('[') == 173;
  473.     $is_ebcdic_POSIX_BC = ord('[') == 187;
  474.  
  475. However, it would be unwise to write tests such as:
  476.  
  477.     $is_ascii = "\r" ne chr(13);  #  WRONG
  478.     $is_ascii = "\n" ne chr(10);  #  ILL ADVISED
  479.  
  480. Obviously the first of these will fail to distinguish most ASCII machines
  481. from either a CCSID 0037, a 1047, or a POSIX-BC EBCDIC machine since "\r" eq 
  482. chr(13) under all of those coded character sets.  But note too that 
  483. because "\n" is chr(13) and "\r" is chr(10) on the MacIntosh (which is an 
  484. ASCII machine) the second C<$is_ascii> test will lead to trouble there.
  485.  
  486. To determine whether or not perl was built under an EBCDIC 
  487. code page you can use the Config module like so:
  488.  
  489.     use Config;
  490.     $is_ebcdic = $Config{'ebcdic'} eq 'define';
  491.  
  492. =head1 CONVERSIONS
  493.  
  494. =head2 tr///
  495.  
  496. In order to convert a string of characters from one character set to 
  497. another a simple list of numbers, such as in the right columns in the
  498. above table, along with perl's tr/// operator is all that is needed.  
  499. The data in the table are in ASCII order hence the EBCDIC columns 
  500. provide easy to use ASCII to EBCDIC operations that are also easily 
  501. reversed.
  502.  
  503. For example, to convert ASCII to code page 037 take the output of the second 
  504. column from the output of recipe 0 (modified to add \\ characters) and use 
  505. it in tr/// like so:
  506.  
  507.     $cp_037 = 
  508.     '\000\001\002\003\234\011\206\177\227\215\216\013\014\015\016\017' .
  509.     '\020\021\022\023\235\205\010\207\030\031\222\217\034\035\036\037' .
  510.     '\200\201\202\203\204\012\027\033\210\211\212\213\214\005\006\007' .
  511.     '\220\221\026\223\224\225\226\004\230\231\232\233\024\025\236\032' .
  512.     '\040\240\342\344\340\341\343\345\347\361\242\056\074\050\053\174' .
  513.     '\046\351\352\353\350\355\356\357\354\337\041\044\052\051\073\254' .
  514.     '\055\057\302\304\300\301\303\305\307\321\246\054\045\137\076\077' .
  515.     '\370\311\312\313\310\315\316\317\314\140\072\043\100\047\075\042' .
  516.     '\330\141\142\143\144\145\146\147\150\151\253\273\360\375\376\261' .
  517.     '\260\152\153\154\155\156\157\160\161\162\252\272\346\270\306\244' .
  518.     '\265\176\163\164\165\166\167\170\171\172\241\277\320\335\336\256' .
  519.     '\136\243\245\267\251\247\266\274\275\276\133\135\257\250\264\327' .
  520.     '\173\101\102\103\104\105\106\107\110\111\255\364\366\362\363\365' .
  521.     '\175\112\113\114\115\116\117\120\121\122\271\373\374\371\372\377' .
  522.     '\134\367\123\124\125\126\127\130\131\132\262\324\326\322\323\325' .
  523.     '\060\061\062\063\064\065\066\067\070\071\263\333\334\331\332\237' ;
  524.  
  525.     my $ebcdic_string = $ascii_string;
  526.     eval '$ebcdic_string =~ tr/\000-\377/' . $cp_037 . '/';
  527.  
  528. To convert from EBCDIC 037 to ASCII just reverse the order of the tr/// 
  529. arguments like so:
  530.  
  531.     my $ascii_string = $ebcdic_string;
  532.     eval '$ascii_string = tr/' . $cp_037 . '/\000-\377/';
  533.  
  534. Similarly one could take the output of the third column from recipe 0 to
  535. obtain a C<$cp_1047> table.  The fourth column of the output from recipe
  536. 0 could provide a C<$cp_posix_bc> table suitable for transcoding as well.
  537.  
  538. =head2 iconv
  539.  
  540. XPG operability often implies the presence of an I<iconv> utility
  541. available from the shell or from the C library.  Consult your system's
  542. documentation for information on iconv.
  543.  
  544. On OS/390 see the iconv(1) man page.  One way to invoke the iconv 
  545. shell utility from within perl would be to:
  546.  
  547.     # OS/390 example
  548.     $ascii_data = `echo '$ebcdic_data'| iconv -f IBM-1047 -t ISO8859-1`
  549.  
  550. or the inverse map:
  551.  
  552.     # OS/390 example
  553.     $ebcdic_data = `echo '$ascii_data'| iconv -f ISO8859-1 -t IBM-1047`
  554.  
  555. For other perl based conversion options see the Convert::* modules on CPAN.
  556.  
  557. =head2 C RTL
  558.  
  559. The OS/390 C run time library provides _atoe() and _etoa() functions.
  560.  
  561. =head1 OPERATOR DIFFERENCES
  562.  
  563. The C<..> range operator treats certain character ranges with 
  564. care on EBCDIC machines.  For example the following array
  565. will have twenty six elements on either an EBCDIC machine
  566. or an ASCII machine:
  567.  
  568.     @alphabet = ('A'..'Z');   #  $#alphabet == 25
  569.  
  570. The bitwise operators such as & ^ | may return different results
  571. when operating on string or character data in a perl program running 
  572. on an EBCDIC machine than when run on an ASCII machine.  Here is
  573. an example adapted from the one in L<perlop>:
  574.  
  575.     # EBCDIC-based examples
  576.     print "j p \n" ^ " a h";                      # prints "JAPH\n"
  577.     print "JA" | "  ph\n";                        # prints "japh\n" 
  578.     print "JAPH\nJunk" & "\277\277\277\277\277";  # prints "japh\n";
  579.     print 'p N$' ^ " E<H\n";                      # prints "Perl\n";
  580.  
  581. An interesting property of the 32 C0 control characters
  582. in the ASCII table is that they can "literally" be constructed
  583. as control characters in perl, e.g. C<(chr(0) eq "\c@")> 
  584. C<(chr(1) eq "\cA")>, and so on.  Perl on EBCDIC machines has been 
  585. ported to take "\c@" to chr(0) and "\cA" to chr(1) as well, but the
  586. thirty three characters that result depend on which code page you are
  587. using.  The table below uses the character names from the previous table 
  588. but with substitutions such as s/START OF/S.O./; s/END OF /E.O./; 
  589. s/TRANSMISSION/TRANS./; s/TABULATION/TAB./; s/VERTICAL/VERT./; 
  590. s/HORIZONTAL/HORIZ./; s/DEVICE CONTROL/D.C./; s/SEPARATOR/SEP./; 
  591. s/NEGATIVE ACKNOWLEDGE/NEG. ACK./;.  The POSIX-BC and 1047 sets are
  592. identical throughout this range and differ from the 0037 set at only 
  593. one spot (21 decimal).  Note that the C<LINE FEED> character
  594. may be generated by "\cJ" on ASCII machines but by "\cU" on 1047 or POSIX-BC 
  595. machines and cannot be generated as a C<"\c.letter."> control character on 
  596. 0037 machines.  Note also that "\c\\" maps to two characters
  597. not one.
  598.  
  599.     chr   ord  8859-1               0037                1047 && POSIX-BC     
  600.     ------------------------------------------------------------------------
  601.     "\c?" 127  <DELETE>             "                   "              ***><
  602.     "\c@"   0  <NULL>               <NULL>              <NULL>         ***><
  603.     "\cA"   1  <S.O. HEADING>       <S.O. HEADING>      <S.O. HEADING> 
  604.     "\cB"   2  <S.O. TEXT>          <S.O. TEXT>         <S.O. TEXT>
  605.     "\cC"   3  <E.O. TEXT>          <E.O. TEXT>         <E.O. TEXT>
  606.     "\cD"   4  <E.O. TRANS.>        <C1 28>             <C1 28> 
  607.     "\cE"   5  <ENQUIRY>            <HORIZ. TAB.>       <HORIZ. TAB.>    
  608.     "\cF"   6  <ACKNOWLEDGE>        <C1 6>              <C1 6>   
  609.     "\cG"   7  <BELL>               <DELETE>            <DELETE>   
  610.     "\cH"   8  <BACKSPACE>          <C1 23>             <C1 23>
  611.     "\cI"   9  <HORIZ. TAB.>        <C1 13>             <C1 13>
  612.     "\cJ"  10  <LINE FEED>          <C1 14>             <C1 14>
  613.     "\cK"  11  <VERT. TAB.>         <VERT. TAB.>        <VERT. TAB.>
  614.     "\cL"  12  <FORM FEED>          <FORM FEED>         <FORM FEED>    
  615.     "\cM"  13  <CARRIAGE RETURN>    <CARRIAGE RETURN>   <CARRIAGE RETURN> 
  616.     "\cN"  14  <SHIFT OUT>          <SHIFT OUT>         <SHIFT OUT>
  617.     "\cO"  15  <SHIFT IN>           <SHIFT IN>          <SHIFT IN>
  618.     "\cP"  16  <DATA LINK ESCAPE>   <DATA LINK ESCAPE>  <DATA LINK ESCAPE> 
  619.     "\cQ"  17  <D.C. ONE>           <D.C. ONE>          <D.C. ONE>
  620.     "\cR"  18  <D.C. TWO>           <D.C. TWO>          <D.C. TWO>
  621.     "\cS"  19  <D.C. THREE>         <D.C. THREE>        <D.C. THREE> 
  622.     "\cT"  20  <D.C. FOUR>          <C1 29>             <C1 29> 
  623.     "\cU"  21  <NEG. ACK.>          <C1 5>              <LINE FEED>    ***
  624.     "\cV"  22  <SYNCHRONOUS IDLE>   <BACKSPACE>         <BACKSPACE>
  625.     "\cW"  23  <E.O. TRANS. BLOCK>  <C1 7>              <C1 7>
  626.     "\cX"  24  <CANCEL>             <CANCEL>            <CANCEL>
  627.     "\cY"  25  <E.O. MEDIUM>        <E.O. MEDIUM>       <E.O. MEDIUM>
  628.     "\cZ"  26  <SUBSTITUTE>         <C1 18>             <C1 18>
  629.     "\c["  27  <ESCAPE>             <C1 15>             <C1 15>
  630.     "\c\\" 28  <FILE SEP.>\         <FILE SEP.>\        <FILE SEP.>\
  631.     "\c]"  29  <GROUP SEP.>         <GROUP SEP.>        <GROUP SEP.>
  632.     "\c^"  30  <RECORD SEP.>        <RECORD SEP.>       <RECORD SEP.>  ***><
  633.     "\c_"  31  <UNIT SEP.>          <UNIT SEP.>         <UNIT SEP.>    ***><
  634.  
  635.  
  636. =head1 FUNCTION DIFFERENCES
  637.  
  638. =over 8
  639.  
  640. =item chr()
  641.  
  642. chr() must be given an EBCDIC code number argument to yield a desired 
  643. character return value on an EBCDIC machine.  For example:
  644.  
  645.     $CAPITAL_LETTER_A = chr(193);
  646.  
  647. =item ord()
  648.  
  649. ord() will return EBCDIC code number values on an EBCDIC machine.
  650. For example:
  651.  
  652.     $the_number_193 = ord("A");
  653.  
  654. =item pack()
  655.  
  656. The c and C templates for pack() are dependent upon character set 
  657. encoding.  Examples of usage on EBCDIC include:
  658.  
  659.     $foo = pack("CCCC",193,194,195,196);
  660.     # $foo eq "ABCD"
  661.     $foo = pack("C4",193,194,195,196);
  662.     # same thing
  663.  
  664.     $foo = pack("ccxxcc",193,194,195,196);
  665.     # $foo eq "AB\0\0CD"
  666.  
  667. =item print()
  668.  
  669. One must be careful with scalars and strings that are passed to
  670. print that contain ASCII encodings.  One common place
  671. for this to occur is in the output of the MIME type header for
  672. CGI script writing.  For example, many perl programming guides 
  673. recommend something similar to:
  674.  
  675.     print "Content-type:\ttext/html\015\012\015\012"; 
  676.     # this may be wrong on EBCDIC
  677.  
  678. Under the IBM OS/390 USS Web Server for example you should instead
  679. write that as:
  680.  
  681.     print "Content-type:\ttext/html\r\n\r\n"; # OK for DGW et alia
  682.  
  683. That is because the translation from EBCDIC to ASCII is done
  684. by the web server in this case (such code will not be appropriate for
  685. the Macintosh however).  Consult your web server's documentation for 
  686. further details.
  687.  
  688. =item printf()
  689.  
  690. The formats that can convert characters to numbers and vice versa
  691. will be different from their ASCII counterparts when executed
  692. on an EBCDIC machine.  Examples include:
  693.  
  694.     printf("%c%c%c",193,194,195);  # prints ABC
  695.  
  696. =item sort()
  697.  
  698. EBCDIC sort results may differ from ASCII sort results especially for 
  699. mixed case strings.  This is discussed in more detail below.
  700.  
  701. =item sprintf()
  702.  
  703. See the discussion of printf() above.  An example of the use
  704. of sprintf would be:
  705.  
  706.     $CAPITAL_LETTER_A = sprintf("%c",193);
  707.  
  708. =item unpack()
  709.  
  710. See the discussion of pack() above.
  711.  
  712. =back
  713.  
  714. =head1 REGULAR EXPRESSION DIFFERENCES
  715.  
  716. As of perl 5.005_03 the letter range regular expression such as 
  717. [A-Z] and [a-z] have been especially coded to not pick up gap 
  718. characters.  For example, characters such as E<ocirc> C<o WITH CIRCUMFLEX> 
  719. that lie between I and J would not be matched by the 
  720. regular expression range C</[H-K]/>.  
  721.  
  722. If you do want to match the alphabet gap characters in a single octet 
  723. regular expression try matching the hex or octal code such 
  724. as C</\313/> on EBCDIC or C</\364/> on ASCII machines to 
  725. have your regular expression match C<o WITH CIRCUMFLEX>.
  726.  
  727. Another construct to be wary of is the inappropriate use of hex or
  728. octal constants in regular expressions.  Consider the following
  729. set of subs:
  730.  
  731.     sub is_c0 {
  732.         my $char = substr(shift,0,1);
  733.         $char =~ /[\000-\037]/;
  734.     }
  735.  
  736.     sub is_print_ascii {
  737.         my $char = substr(shift,0,1);
  738.         $char =~ /[\040-\176]/;
  739.     }
  740.  
  741.     sub is_delete {
  742.         my $char = substr(shift,0,1);
  743.         $char eq "\177";
  744.     }
  745.  
  746.     sub is_c1 {
  747.         my $char = substr(shift,0,1);
  748.         $char =~ /[\200-\237]/;
  749.     }
  750.  
  751.     sub is_latin_1 {
  752.         my $char = substr(shift,0,1);
  753.         $char =~ /[\240-\377]/;
  754.     }
  755.  
  756. The above would be adequate if the concern was only with numeric code points.
  757. However, the concern may be with characters rather than code points 
  758. and on an EBCDIC machine it may be desirable for constructs such as 
  759. C<if (is_print_ascii("A")) {print "A is a printable character\n";}> to print
  760. out the expected message.  One way to represent the above collection
  761. of character classification subs that is capable of working across the
  762. four coded character sets discussed in this document is as follows:
  763.  
  764.     sub Is_c0 {
  765.         my $char = substr(shift,0,1);
  766.         if (ord('^')==94)  { # ascii
  767.             return $char =~ /[\000-\037]/;
  768.         } 
  769.         if (ord('^')==176) { # 37
  770.             return $char =~ /[\000-\003\067\055-\057\026\005\045\013-\023\074\075\062\046\030\031\077\047\034-\037]/;
  771.         }
  772.         if (ord('^')==95 || ord('^')==106) { # 1047 || posix-bc
  773.             return $char =~ /[\000-\003\067\055-\057\026\005\025\013-\023\074\075\062\046\030\031\077\047\034-\037]/;
  774.         }
  775.     }
  776.  
  777.     sub Is_print_ascii {
  778.         my $char = substr(shift,0,1);
  779.         $char =~ /[ !"\#\$%&'()*+,\-.\/0-9:;<=>?\@A-Z[\\\]^_`a-z{|}~]/;
  780.     }
  781.  
  782.     sub Is_delete {
  783.         my $char = substr(shift,0,1);
  784.         if (ord('^')==94)  { # ascii
  785.             return $char eq "\177";
  786.         }
  787.         else  {              # ebcdic
  788.             return $char eq "\007";
  789.         }
  790.     }
  791.  
  792.     sub Is_c1 {
  793.         my $char = substr(shift,0,1);
  794.         if (ord('^')==94)  { # ascii
  795.             return $char =~ /[\200-\237]/;
  796.         }
  797.         if (ord('^')==176) { # 37
  798.             return $char =~ /[\040-\044\025\006\027\050-\054\011\012\033\060\061\032\063-\066\010\070-\073\040\024\076\377]/;
  799.         }
  800.         if (ord('^')==95)  { # 1047
  801.             return $char =~ /[\040-\045\006\027\050-\054\011\012\033\060\061\032\063-\066\010\070-\073\040\024\076\377]/;
  802.         }
  803.         if (ord('^')==106) { # posix-bc
  804.             return $char =~ 
  805.               /[\040-\045\006\027\050-\054\011\012\033\060\061\032\063-\066\010\070-\073\040\024\076\137]/;
  806.         }
  807.     }
  808.  
  809.     sub Is_latin_1 {
  810.         my $char = substr(shift,0,1);
  811.         if (ord('^')==94)  { # ascii
  812.             return $char =~ /[\240-\377]/;
  813.         }
  814.         if (ord('^')==176) { # 37
  815.             return $char =~ 
  816.               /[\101\252\112\261\237\262\152\265\275\264\232\212\137\312\257\274\220\217\352\372\276\240\266\263\235\332\233\213\267\270\271\253\144\145\142\146\143\147\236\150\164\161-\163\170\165-\167\254\151\355\356\353\357\354\277\200\375\376\373\374\255\256\131\104\105\102\106\103\107\234\110\124\121-\123\130\125-\127\214\111\315\316\313\317\314\341\160\335\336\333\334\215\216\337]/;
  817.         }
  818.         if (ord('^')==95)  { # 1047
  819.             return $char =~
  820.               /[\101\252\112\261\237\262\152\265\273\264\232\212\260\312\257\274\220\217\352\372\276\240\266\263\235\332\233\213\267\270\271\253\144\145\142\146\143\147\236\150\164\161-\163\170\165-\167\254\151\355\356\353\357\354\277\200\375\376\373\374\272\256\131\104\105\102\106\103\107\234\110\124\121-\123\130\125-\127\214\111\315\316\313\317\314\341\160\335\336\333\334\215\216\337]/; 
  821.         }
  822.         if (ord('^')==106) { # posix-bc
  823.             return $char =~ 
  824.               /[\101\252\260\261\237\262\320\265\171\264\232\212\272\312\257\241\220\217\352\372\276\240\266\263\235\332\233\213\267\270\271\253\144\145\142\146\143\147\236\150\164\161-\163\170\165-\167\254\151\355\356\353\357\354\277\200\340\376\335\374\255\256\131\104\105\102\106\103\107\234\110\124\121-\123\130\125-\127\214\111\315\316\313\317\314\341\160\300\336\333\334\215\216\337]/;
  825.         }
  826.     }
  827.  
  828. Note however that only the C<Is_ascii_print()> sub is really independent 
  829. of coded character set.  Another way to write C<Is_latin_1()> would be 
  830. to use the characters in the range explicitly:
  831.  
  832.     sub Is_latin_1 {
  833.         my $char = substr(shift,0,1);
  834.         $char =~ /[áíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ]/;
  835.     }
  836.  
  837. Although that form may run into trouble in network transit (due to the 
  838. presence of 8 bit characters) or on non ISO-Latin character sets.
  839.  
  840. =head1 SOCKETS
  841.  
  842. Most socket programming assumes ASCII character encodings in network
  843. byte order.  Exceptions can include CGI script writing under a
  844. host web server where the server may take care of translation for you.
  845. Most host web servers convert EBCDIC data to ISO-8859-1 or Unicode on
  846. output.
  847.  
  848. =head1 SORTING
  849.  
  850. One big difference between ASCII based character sets and EBCDIC ones
  851. are the relative positions of upper and lower case letters and the
  852. letters compared to the digits.  If sorted on an ASCII based machine the
  853. two letter abbreviation for a physician comes before the two letter
  854. for drive, that is:
  855.  
  856.     @sorted = sort(qw(Dr. dr.));  # @sorted holds ('Dr.','dr.') on ASCII,
  857.                                   # but ('dr.','Dr.') on EBCDIC
  858.  
  859. The property of lower case before uppercase letters in EBCDIC is
  860. even carried to the Latin 1 EBCDIC pages such as 0037 and 1047.
  861. An example would be that E<Euml> C<E WITH DIAERESIS> (203) comes 
  862. before E<euml> C<e WITH DIAERESIS> (235) on an ASCII machine, but 
  863. the latter (83) comes before the former (115) on an EBCDIC machine.  
  864. (Astute readers will note that the upper case version of E<szlig> 
  865. C<SMALL LETTER SHARP S> is simply "SS" and that the upper case version of 
  866. E<yuml> C<y WITH DIAERESIS> is not in the 0..255 range but it is 
  867. at U+x0178 in Unicode, or C<"\x{178}"> in a Unicode enabled Perl).
  868.  
  869. The sort order will cause differences between results obtained on
  870. ASCII machines versus EBCDIC machines.  What follows are some suggestions
  871. on how to deal with these differences.
  872.  
  873. =head2 Ignore ASCII vs. EBCDIC sort differences.
  874.  
  875. This is the least computationally expensive strategy.  It may require
  876. some user education.
  877.  
  878. =head2 MONO CASE then sort data.
  879.  
  880. In order to minimize the expense of mono casing mixed test try to
  881. C<tr///> towards the character set case most employed within the data.
  882. If the data are primarily UPPERCASE non Latin 1 then apply tr/[a-z]/[A-Z]/
  883. then sort().  If the data are primarily lowercase non Latin 1 then
  884. apply tr/[A-Z]/[a-z]/ before sorting.  If the data are primarily UPPERCASE
  885. and include Latin-1 characters then apply:  
  886.  
  887.     tr/[a-z]/[A-Z]/; 
  888.     tr/[αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷°∙·√ⁿ²■]/[└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╪┘┌█▄▌▐]/;
  889.     s/▀/SS/g; 
  890.  
  891. then sort().  Do note however that such Latin-1 manipulation does not 
  892. address the E<yuml> C<y WITH DIAERESIS> character that will remain at 
  893. code point 255 on ASCII machines, but 223 on most EBCDIC machines 
  894. where it will sort to a place less than the EBCDIC numerals.  With a 
  895. Unicode enabled Perl you might try:
  896.  
  897.     tr/^?/\x{178}/;
  898.  
  899. The strategy of mono casing data before sorting does not preserve the case 
  900. of the data and may not be acceptable for that reason.
  901.  
  902. =head2 Convert, sort data, then re convert.
  903.  
  904. This is the most expensive proposition that does not employ a network
  905. connection.
  906.  
  907. =head2 Perform sorting on one type of machine only.
  908.  
  909. This strategy can employ a network connection.  As such
  910. it would be computationally expensive.
  911.  
  912. =head1 TRANFORMATION FORMATS
  913.  
  914. There are a variety of ways of transforming data with an intra character set 
  915. mapping that serve a variety of purposes.  Sorting was discussed in the 
  916. previous section and a few of the other more popular mapping techniques are 
  917. discussed next.
  918.  
  919. =head2 URL decoding and encoding
  920.  
  921. Note that some URLs have hexadecimal ASCII code points in them in an
  922. attempt to overcome character or protocol limitation issues.  For example 
  923. the tilde character is not on every keyboard hence a URL of the form:
  924.  
  925.     http://www.pvhp.com/~pvhp/
  926.  
  927. may also be expressed as either of:
  928.  
  929.     http://www.pvhp.com/%7Epvhp/
  930.  
  931.     http://www.pvhp.com/%7epvhp/
  932.  
  933. where 7E is the hexadecimal ASCII code point for '~'.  Here is an example
  934. of decoding such a URL under CCSID 1047:
  935.  
  936.     $url = 'http://www.pvhp.com/%7Epvhp/';
  937.     # this array assumes code page 1047
  938.     my @a2e_1047 = (
  939.           0,  1,  2,  3, 55, 45, 46, 47, 22,  5, 21, 11, 12, 13, 14, 15,
  940.          16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31,
  941.          64, 90,127,123, 91,108, 80,125, 77, 93, 92, 78,107, 96, 75, 97,
  942.         240,241,242,243,244,245,246,247,248,249,122, 94, 76,126,110,111,
  943.         124,193,194,195,196,197,198,199,200,201,209,210,211,212,213,214,
  944.         215,216,217,226,227,228,229,230,231,232,233,173,224,189, 95,109,
  945.         121,129,130,131,132,133,134,135,136,137,145,146,147,148,149,150,
  946.         151,152,153,162,163,164,165,166,167,168,169,192, 79,208,161,  7,
  947.          32, 33, 34, 35, 36, 37,  6, 23, 40, 41, 42, 43, 44,  9, 10, 27,
  948.          48, 49, 26, 51, 52, 53, 54,  8, 56, 57, 58, 59,  4, 20, 62,255,
  949.          65,170, 74,177,159,178,106,181,187,180,154,138,176,202,175,188,
  950.         144,143,234,250,190,160,182,179,157,218,155,139,183,184,185,171,
  951.         100,101, 98,102, 99,103,158,104,116,113,114,115,120,117,118,119,
  952.         172,105,237,238,235,239,236,191,128,253,254,251,252,186,174, 89,
  953.          68, 69, 66, 70, 67, 71,156, 72, 84, 81, 82, 83, 88, 85, 86, 87,
  954.         140, 73,205,206,203,207,204,225,112,221,222,219,220,141,142,223
  955.     );
  956.     $url =~ s/%([0-9a-fA-F]{2})/pack("c",$a2e_1047[hex($1)])/ge;
  957.  
  958. Conversely, here is a partial solution for the task of encoding such 
  959. a URL under the 1047 code page:
  960.  
  961.     $url = 'http://www.pvhp.com/~pvhp/';
  962.     # this array assumes code page 1047
  963.     my @e2a_1047 = (
  964.           0,  1,  2,  3,156,  9,134,127,151,141,142, 11, 12, 13, 14, 15,
  965.          16, 17, 18, 19,157, 10,  8,135, 24, 25,146,143, 28, 29, 30, 31,
  966.         128,129,130,131,132,133, 23, 27,136,137,138,139,140,  5,  6,  7,
  967.         144,145, 22,147,148,149,150,  4,152,153,154,155, 20, 21,158, 26,
  968.          32,160,226,228,224,225,227,229,231,241,162, 46, 60, 40, 43,124,
  969.          38,233,234,235,232,237,238,239,236,223, 33, 36, 42, 41, 59, 94,
  970.          45, 47,194,196,192,193,195,197,199,209,166, 44, 37, 95, 62, 63,
  971.         248,201,202,203,200,205,206,207,204, 96, 58, 35, 64, 39, 61, 34,
  972.         216, 97, 98, 99,100,101,102,103,104,105,171,187,240,253,254,177,
  973.         176,106,107,108,109,110,111,112,113,114,170,186,230,184,198,164,
  974.         181,126,115,116,117,118,119,120,121,122,161,191,208, 91,222,174,
  975.         172,163,165,183,169,167,182,188,189,190,221,168,175, 93,180,215,
  976.         123, 65, 66, 67, 68, 69, 70, 71, 72, 73,173,244,246,242,243,245,
  977.         125, 74, 75, 76, 77, 78, 79, 80, 81, 82,185,251,252,249,250,255,
  978.          92,247, 83, 84, 85, 86, 87, 88, 89, 90,178,212,214,210,211,213,
  979.          48, 49, 50, 51, 52, 53, 54, 55, 56, 57,179,219,220,217,218,159
  980.     );
  981.     # The following regular expression does not address the 
  982.     # mappings for: ('.' => '%2E', '/' => '%2F', ':' => '%3A') 
  983.     $url =~ s/([\t "#%&\(\),;<=>\?\@\[\\\]^`{|}~])/sprintf("%%%02X",$e2a_1047[ord($1)])/ge;
  984.  
  985. where a more complete solution would split the URL into components 
  986. and apply a full s/// substitution only to the appropriate parts.
  987.  
  988. In the remaining examples a @e2a or @a2e array may be employed
  989. but the assignment will not be shown explicitly.  For code page 1047
  990. you could use the @a2e_1047 or @e2a_1047 arrays just shown.
  991.  
  992. =head2 uu encoding and decoding
  993.  
  994. The C<u> template to pack() or unpack() will render EBCDIC data in EBCDIC 
  995. characters equivalent to their ASCII counterparts.  For example, the 
  996. following will print "Yes indeed\n" on either an ASCII or EBCDIC computer:
  997.  
  998.     $all_byte_chrs = '';
  999.     for (0..255) { $all_byte_chrs .= chr($_); }
  1000.     $uuencode_byte_chrs = pack('u', $all_byte_chrs);
  1001.     ($uu = <<'    ENDOFHEREDOC') =~ s/^\s*//gm;
  1002.     M``$"`P0%!@<("0H+#`T.#Q`1$A,4%187&!D:&QP='A\@(2(C)"4F)R@I*BLL
  1003.     M+2XO,#$R,S0U-C<X.3H[/#T^/T!!0D-$149'2$E*2TQ-3D]045)35%565UA9
  1004.     M6EM<75Y?8&%B8V1E9F=H:6IK;&UN;W!Q<G-T=79W>'EZ>WQ]?G^`@8*#A(6&
  1005.     MAXB)BHN,C8Z/D)&2DY25EI>8F9J;G)V>GZ"AHJ.DI::GJ*FJJZRMKJ^PL;*S
  1006.     MM+6VM[BYNKN\O;Z_P,'"P\3%QL?(R<K+S,W.S]#1TM/4U=;7V-G:V]S=WM_@
  1007.     ?X>+CY.7FY^CIZNOL[>[O\/'R\_3U]O?X^?K[_/W^_P``
  1008.     ENDOFHEREDOC
  1009.     if ($uuencode_byte_chrs eq $uu) {
  1010.         print "Yes ";
  1011.     }
  1012.     $uudecode_byte_chrs = unpack('u', $uuencode_byte_chrs);
  1013.     if ($uudecode_byte_chrs eq $all_byte_chrs) {
  1014.         print "indeed\n";
  1015.     }
  1016.  
  1017. Here is a very spartan uudecoder that will work on EBCDIC provided
  1018. that the @e2a array is filled in appropriately:
  1019.  
  1020.     #!/usr/local/bin/perl
  1021.     @e2a = ( # this must be filled in
  1022.            );
  1023.     $_ = <> until ($mode,$file) = /^begin\s*(\d*)\s*(\S*)/;
  1024.     open(OUT, "> $file") if $file ne "";
  1025.     while(<>) {
  1026.         last if /^end/;
  1027.         next if /[a-z]/;
  1028.         next unless int(((($e2a[ord()] - 32 ) & 077) + 2) / 3) ==
  1029.             int(length() / 4);
  1030.         print OUT unpack("u", $_);
  1031.     }
  1032.     close(OUT);
  1033.     chmod oct($mode), $file;
  1034.  
  1035.  
  1036. =head2 Quoted-Printable encoding and decoding
  1037.  
  1038. On ASCII encoded machines it is possible to strip characters outside of
  1039. the printable set using:
  1040.  
  1041.     # This QP encoder works on ASCII only
  1042.     $qp_string =~ s/([=\x00-\x1F\x80-\xFF])/sprintf("=%02X",ord($1))/ge;
  1043.  
  1044. Whereas a QP encoder that works on both ASCII and EBCDIC machines 
  1045. would look somewhat like the following (where the EBCDIC branch @e2a 
  1046. array is omitted for brevity):
  1047.  
  1048.     if (ord('A') == 65) {    # ASCII
  1049.         $delete = "\x7F";    # ASCII
  1050.         @e2a = (0 .. 255)    # ASCII to ASCII identity map
  1051.     }
  1052.     else {                   # EBCDIC
  1053.         $delete = "\x07";    # EBCDIC
  1054.         @e2a =               # EBCDIC to ASCII map (as shown above)
  1055.     }
  1056.     $qp_string =~
  1057.       s/([^ !"\#\$%&'()*+,\-.\/0-9:;<>?\@A-Z[\\\]^_`a-z{|}~$delete])/sprintf("=%02X",$e2a[ord($1)])/ge;
  1058.  
  1059. (although in production code the substitutions might be done
  1060. in the EBCDIC branch with the @e2a array and separately in the 
  1061. ASCII branch without the expense of the identity map).
  1062.  
  1063. Such QP strings can be decoded with:
  1064.  
  1065.     # This QP decoder is limited to ASCII only
  1066.     $string =~ s/=([0-9A-Fa-f][0-9A-Fa-f])/chr hex $1/ge;
  1067.     $string =~ s/=[\n\r]+$//;
  1068.  
  1069. Whereas a QP decoder that works on both ASCII and EBCDIC machines 
  1070. would look somewhat like the following (where the @a2e array is
  1071. omitted for brevity):
  1072.  
  1073.     $string =~ s/=([0-9A-Fa-f][0-9A-Fa-f])/chr $a2e[hex $1]/ge;
  1074.     $string =~ s/=[\n\r]+$//;
  1075.  
  1076. =head2 Caesarian cyphers
  1077.  
  1078. The practice of shifting an alphabet one or more characters for encipherment
  1079. dates back thousands of years and was explicitly detailed by Gaius Julius
  1080. Caesar in his B<Gallic Wars> text.  A single alphabet shift is sometimes 
  1081. referred to as a rotation and the shift amount is given as a number $n after
  1082. the string 'rot' or "rot$n".  Rot0 and rot26 would designate identity maps 
  1083. on the 26 letter English version of the Latin alphabet.  Rot13 has the 
  1084. interesting property that alternate subsequent invocations are identity maps 
  1085. (thus rot13 is its own non-trivial inverse in the group of 26 alphabet 
  1086. rotations).  Hence the following is a rot13 encoder and decoder that will 
  1087. work on ASCII and EBCDIC machines:
  1088.  
  1089.     #!/usr/local/bin/perl
  1090.  
  1091.     while(<>){
  1092.         tr/n-za-mN-ZA-M/a-zA-Z/;
  1093.         print;
  1094.     }
  1095.  
  1096. In one-liner form:
  1097.  
  1098.     perl -ne 'tr/n-za-mN-ZA-M/a-zA-Z/;print'
  1099.  
  1100.  
  1101. =head1 Hashing order and checksums
  1102.  
  1103. XXX
  1104.  
  1105. =head1 I18N AND L10N
  1106.  
  1107. Internationalization(I18N) and localization(L10N) are supported at least 
  1108. in principle even on EBCDIC machines.  The details are system dependent 
  1109. and discussed under the L<perlebcdic/OS ISSUES> section below.
  1110.  
  1111. =head1 MULTI OCTET CHARACTER SETS
  1112.  
  1113. Multi byte EBCDIC code pages; Unicode, UTF-8, UTF-EBCDIC, XXX.
  1114.  
  1115. =head1 OS ISSUES
  1116.  
  1117. There may be a few system dependent issues 
  1118. of concern to EBCDIC Perl programmers.
  1119.  
  1120. =head2 OS/400 
  1121.  
  1122. The PASE environment.
  1123.  
  1124. =over 8
  1125.  
  1126. =item IFS access
  1127.  
  1128. XXX.
  1129.  
  1130. =back
  1131.  
  1132. =head2 OS/390 
  1133.  
  1134. Perl runs under Unix Systems Services or USS.
  1135.  
  1136. =over 8
  1137.  
  1138. =item chcp
  1139.  
  1140. B<chcp> is supported as a shell utility for displaying and changing 
  1141. one's code page.  See also L<chcp>.
  1142.  
  1143. =item dataset access
  1144.  
  1145. For sequential data set access try:
  1146.  
  1147.     my @ds_records = `cat //DSNAME`;
  1148.  
  1149. or:
  1150.  
  1151.     my @ds_records = `cat //'HLQ.DSNAME'`;
  1152.  
  1153. See also the OS390::Stdio module on CPAN.
  1154.  
  1155. =item OS/390 iconv
  1156.  
  1157. B<iconv> is supported as both a shell utility and a C RTL routine.
  1158. See also the iconv(1) and iconv(3) manual pages.
  1159.  
  1160. =item locales
  1161.  
  1162. On OS/390 see L<locale> for information on locales.  The L10N files
  1163. are in F</usr/nls/locale>.  $Config{d_setlocale} is 'define' on OS/390.
  1164.  
  1165. =back
  1166.  
  1167. =head2 VM/ESA?
  1168.  
  1169. XXX.
  1170.  
  1171. =head2 POSIX-BC?
  1172.  
  1173. XXX.
  1174.  
  1175. =head1 BUGS
  1176.  
  1177. This pod document contains literal Latin 1 characters and may encounter 
  1178. translation difficulties.  In particular one popular nroff implementation 
  1179. was known to strip accented characters to their unaccented counterparts 
  1180. while attempting to view this document through the B<pod2man> program 
  1181. (for example, you may see a plain C<y> rather than one with a diaeresis 
  1182. as in E<yuml>).  Another nroff truncated the resultant man page at
  1183. the first occurence of 8 bit characters.
  1184.  
  1185. Not all shells will allow multiple C<-e> string arguments to perl to
  1186. be concatenated together properly as recipes 2, 3, and 4 might seem
  1187. to imply.
  1188.  
  1189. Perl does not yet work with any Unicode features on EBCDIC platforms.
  1190.  
  1191. =head1 SEE ALSO
  1192.  
  1193. L<perllocale>, L<perlfunc>.
  1194.  
  1195. =head1 REFERENCES
  1196.  
  1197. http://anubis.dkuug.dk/i18n/charmaps
  1198.  
  1199. http://www.unicode.org/
  1200.  
  1201. http://www.unicode.org/unicode/reports/tr16/
  1202.  
  1203. http://www.wps.com/texts/codes/
  1204. B<ASCII: American Standard Code for Information Infiltration> Tom Jennings,
  1205. September 1999.
  1206.  
  1207. B<The Unicode Standard Version 2.0> The Unicode Consortium, 
  1208. ISBN 0-201-48345-9, Addison Wesley Developers Press, July 1996. 
  1209.  
  1210. B<The Unicode Standard Version 3.0> The Unicode Consortium, Lisa Moore ed., 
  1211. ISBN 0-201-61633-5, Addison Wesley Developers Press, February 2000. 
  1212.  
  1213. B<CDRA: IBM - Character Data Representation Architecture - 
  1214. Reference and Registry>, IBM SC09-2190-00, December 1996. 
  1215.  
  1216. "Demystifying Character Sets", Andrea Vine, Multilingual Computing 
  1217. & Technology, B<#26 Vol. 10 Issue 4>, August/September 1999;
  1218. ISSN 1523-0309; Multilingual Computing Inc. Sandpoint ID, USA.
  1219.  
  1220. B<Codes, Ciphers, and Other Cryptic and Clandestine Communication>
  1221. Fred B. Wrixon, ISBN 1-57912-040-7, Black Dog & Leventhal Publishers,
  1222. 1998.
  1223.  
  1224. =head1 AUTHOR
  1225.  
  1226. Peter Prymmer pvhp@best.com wrote this in 1999 and 2000 
  1227. with CCSID 0819 and 0037 help from Chris Leach and 
  1228. AndrE<eacute> Pirard A.Pirard@ulg.ac.be as well as POSIX-BC 
  1229. help from Thomas Dorner Thomas.Dorner@start.de.
  1230. Thanks also to Vickie Cooper, Philip Newton, William Raffloer, and 
  1231. Joe Smith.  Trademarks, registered trademarks, service marks and 
  1232. registered service marks used in this document are the property of 
  1233. their respective owners.
  1234.  
  1235.  
  1236.