AS400いわゆるIBMiには、シフト文字という意味不明な文字がある。
普通「アイウエオ」なら10バイトのはずだが、AS400では、12バイトになる。これは先頭と最後が2バイト文字の場合は、前後にそれぞれ1バイトづつ足されるからだ。他にも発生条件があるのでまとめると、
発生条件は、
・先頭で2バイト文字の場合は+1バイト
・最後で2バイト文字の場合は+1バイト
・文字列で1バイト文字と2バイト文字が隣になれば+1バイト
になる。
「aありがとう」は、13バイト
「あaりがとう」は、15バイト
になる。
当然のことながら、
「arigatou」は、8バイト
だ。
それゆえ、こんなロジックを考えてみた。文字列を1つづつ見て、バイト数を計算するのだ。これしか考えられないのでこうしている。
いいやり方があったら教えてほしい。
<!DOCTYPE> <html lang="ja"> <head> <meta charset="utf-8"> <title>テスト</title> </head> <body> <form name="myForm"> <input name="text1" type="text" id="text1" size="40"> <input type="button" onClick="alert(IBMBytes(document.myForm.text1.value));" value="バイト数は?"> </form> <script type="text/javascript"> //1文字のバイト数を戻す function getBytes(strSrc){ var len = 0; //カウント //urlエンコード strSrc = escape(strSrc); if(strSrc.substr(0,1) == "%"){ if(strSrc.substr(1,1) == "u"){ len = 2; }else{ len = 1; } }else{ len = 1; } return len; } //AS400シフト文字を計算して文字列のバイト数を返す function IBMBytes(Stringi){ var strCnt = 0; //引数の文字数 var Now = 0; //現在の文字のバイト数 var Cnt = 0; //カウント var Prv = 0; //1つ前の文字のバイト数 //引数の文字数を取得 strCnt = Stringi.length; //文字列の左から1文字づつチェック for (i = 0; i < strCnt; i++){ //バイト数を取得 Now = getBytes(Stringi.substr(i,1)); //最初の文字、かつ、2バイト文字ならば、シフト文字分追加 if (i == 0 && Now == 2) { Cnt = Cnt + 1; } //最後の文字、かつ、2バイト文字ならば、シフト文字分追加 if (i == strCnt - 1 && Now == 2) { Cnt = Cnt + 1; } //最初の文字でなく、かつ、1つ前の文字とバイト数が違う場合、シフト文字分追加 if (i != 0 && Prv != Now) { Cnt = Cnt + 1; } //読んだ文字のバイト数を足しこみ Cnt = Cnt + Now; //読んだ文字のバイト数を比較のため1つ前に保管 Prv = Now; } return Cnt; } </script> </body> </html>
コメント