10年以上前から何度かQRコードの生成プログラムの自作を試みて、
「リード・ソロモン符号」とか「ガロア拡大体」とか、理解のできない算数が出てきて断念してきたんだが、
GF(2^8)?←これの算出プログラムができた。
「エラー訂正コードの生成多項式」というのがQRの仕様書に記載されているんだが、
生成多項式とGF(2^8)は定数的な感じで使ってコードが生成できそうなんで、QRコード作れそうな感じするわ。
↓GF(2^8)の生成コードサンプル
#!/usr/bin/perl
$bit=0b00000001;
print $bit."\n";
for($i=1;$i<256;$i++){
if($bit<128){
$bit<<=1;
}else{
$bit=$bit-128<<1^0b00011101;
}
print $bit."\n";
}
詳細に説明すると、
GF(2^8)の指数と整数の対応を事前に用意しておいて計算に使いたいが、
指数0に対応する整数は1なので、
$bit=0b00000001;
と2進の1を初期値として用意する。(0b00000001=1だから、単に1で良いのだが、わかりやすく2進で)
普段2進とか使わないが、Perlでは数値の先頭に「0b」で2進数が扱える。
指数は0から255までで、0は初期値なので1から255までループで求めていく。
指数が1増えるごとに左シフトするのだが、桁溢れした場合は00011101とXORする。
桁溢れするということは直前の値が128以上なので、128以上と未満で分ける。
ビット演算とか普段使わないが、
左シフトは「<<」で右項の値の分だけ左シフトする。「<<=」で代入できる。
XORは「^」(この記号は「アクサン シルコンフレクス」って言うらしい)でできる。
「^」だとべき乗演算子ぽいが、Perlのべき乗は「**」だからね。
シフト演算子は減算演算子より優先順位が低くて、XORは更に低いのでカッコは要らない。
まあ、カッコつけたほうがわかりやすいかも。
指数0: 00000001 = 1
指数1: 00000010 = 2
指数2: 00000100 = 4
指数3: 00001000 = 8
指数4: 00010000 = 16
指数5: 00100000 = 32
指数6: 01000000 = 64
指数7: 10000010 = 128
指数8: 00011101 = 29
指数9: 00111010 = 58
.
.
.
指数255: 00000001 = 1
↑こんな感じの数値を求めたかったが、期待した値が出せた。