« 「アサヒカメラ」休刊 ・・・図書館の本はどうなる | トップページ | 今日の「トコーソー」反対ポスター »

2020年10月21日 (水)

gawk 文字列から1文字を取り出して8bit数値として扱いたい

「XOR」によるサムチェック・コードの生成、この処理
の確認用テストプログラムの作成に手こずりました。

通信電文の処理ですんで、CR、LFで区切られたテキスト。
GAWKを使ってチェックしたろっと、
  ちょちょいと・・・のはずが・・・

手順としてはこんなの
  (実際はもうチョイ別の処理も
   入りますが、核の部分だけ)

・入力した1行文字列の文字数を数える。
・先頭から1文字取り出す。
・順にXORしてサムチェックコードを作る。
・全文字完了で2桁の16進値で出力。

試したのはこんなGAWKのコード。

# 文字コードをXORしたい
BEGIN{
a = "ABCDEF"; # チェック文字
n = length(a); # 文字数
sum = 0; # XOR結果
for(i = 1; i <= n; i++){ # 先頭=1から最後まで
c = substr(a, i , 1); # 1文字取り出し
printf("%c", c); # ★1 確認で出力
printf("(%02X)", c); # ★2 HEXで出力
sum = xor(sum, c); # ★3 XOR演算
sum = and(sum, 255); # 00~FFでマスク
}
printf(" : %02X\n", sum); # 結果出力 sum
}

しかし結果はこんなのに。

  A(00)B(00)C(00)D(00)E(00)F(00) : 00

取り出した1文字を、printf("%c",c)で文字として出力
できていますが、8bit数値としての処理ができてません。
ゼロのまま。
  ★1は動作。
  ★2、★3がゼロのまま。

  「c + 0」とか・・・(awkでは+0で変数が数値になる)
  「int(c)」とかを試しましたがダメ。

たしか「昔に同じことをしたよな~」っと思い出して
古いプログラムを探しますと、この解決方法が出てきました。

ちょっと面倒ですが、まず0~255の値に対する配列を作ります。
その配列番号として使うのはsprintf("%c",i)で作った8bit文字
その中に0~255の数値を入れます。

以後、このテーブルを使って8bit文字の数値を得ます。
すると、XOR演算や16進での出力ができるという仕掛け。

こんなテストプログラム。

# 文字コードをXORしたい
BEGIN{
a = "ABCDEF"; # チェック文字
# 0~255の数字テーブルを作成
for(i = 0; i < 256; i++){ # 0~255
t = sprintf("%c", i); # 配列番号を文字で
tbl[t] = i; # 値をテーブルに入れる
}
# 実行
n = length(a); # 文字数
sum = 0; # XOR結果
for(i = 1; i <= n; i++){ # 先頭=1から最後まで
c = substr(a, i , 1); # 1文字取り出し
printf("%c", c); # ★1 確認で出力
printf("(%02X)", tbl[c]); # ★2 HEXで出力
sum = xor(sum, tbl[c]); # ★3 XOR演算
sum = and(sum, 255); # 00~FFでマスク
}
printf(" : %02X\n", sum); # 結果出力 sum
}

結果、ちゃんと16進値が出るようになりました。

  A(41)B(42)C(43)D(44)E(45)F(46) : 07

めでたし、めでたし。


|

« 「アサヒカメラ」休刊 ・・・図書館の本はどうなる | トップページ | 今日の「トコーソー」反対ポスター »

トラブル遭遇」カテゴリの記事

AWK(GAWK)」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




« 「アサヒカメラ」休刊 ・・・図書館の本はどうなる | トップページ | 今日の「トコーソー」反対ポスター »