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>


コメント