シーザー暗号
シーザ暗号 - みずぴー日記 にインスパイヤされてシーザー暗号の暗号化と復号化を行ってみました。
awk には chr() 関数も ord() 関数も用意されていませんが、ASCII の範囲であれば gawk をインストールした時に /usr/share/awk/ord.awk などにインストールされますので、ここを使います。 gawk であればプラグマとして組み込めますが、nawk も想定して、ord.awk をほぼそのまま載せています。
#! /usr/local/bin/nawk -f
# caesar_cipher.awk
# シーザー暗号化、復号化します。
# usage: nawk -f caesar_cipher.awk
BEGIN {
print encode_caesar_cipher("HAL", 1); # エンコード
print decode_caesar_cipher("IBM", 1); # デコード
}
# encode_caesar_cipher(): シーザー暗号化
# in: 文字列 (str)
# 数値 (num)
# out: 文字列 (str) を数値 (num) だけシフトさせたシーザー暗号
function encode_caesar_cipher(str, num, new_str, ord_num) {
num_str = split(str, arr_str, "");
for (i = 1; i <= num_str; i++) {
ord_num = (ord(arr_str[i]) + num >= 90) ? \
(ord(arr_str[i]) + num) % 90 + 64 : \
ord(arr_str[i]) + num;
new_str = new_str chr(ord_num);
}
return new_str;
}
# decode_caesar_cipher(): シーザー復号化
# in: 文字列 (str)
# 数値 (num)
# out: 文字列 (str) を数値 (num) だけシフトさせたシーザー複合
function decode_caesar_cipher(str, num, new_str, ord_num) {
num_str = split(str, arr_str, "");
for (i = 1; i <= num_str; i++) {
ord_num = (ord(arr_str[i]) - num <= 64) ? \
90 - 64 + (ord(arr_str[i]) - num) : \
ord(arr_str[i]) - num;
new_str = new_str chr(ord_num);
}
return new_str;
}
# ord() と chr() 関数
# Ref.: /usr/share/awk/ord.awk
function _ord_init( low, high, i, t) {
low = sprintf("%c", 7) # BEL is ascii 7
if (low == "\a") { # regular ascii
low = 0;
high = 127;
} else if (sprintf("%c", 128 + 7) == "\a") {
# ascii, mark parity
low = 128;
high = 255;
} else { # ebcdic(!)
low = 0;
high = 255;
}
for (i = low; i <= high; i++) {
t = sprintf("%c", i);
_ord_[t] = i;
}
}
function ord(str, c) {
_ord_init();
# only first character is of interest
c = substr(str, 1, 1);
return _ord_[c];
}
function chr(c) {
# force c to be numeric by adding 0
return sprintf("%c", c + 0);
}
シーザー暗号として思いついたものが、『2001 年宇宙の旅』のコンピュータ HAL と IBM の関係だったので、これを例として用います。 (暗号でも何でもないかもしれませんが)
$ nawk -f caesar_cipher.awk IBM HAL
"HAL" が "IBM" に、"IBM" が "HAL" に変換されました。 この場合には 1 文字シフトになります。




