glibcのmemfrob関数
少し前に、glibcにmemfrob
という関数があることを知りました。
指定したメモリ領域を暗号化する関数らしいです。
memfrob関数
#define _GNU_SOURCE
#include <string.h>
void *memfrob(void *s, size_t n);
manページ では以下のように説明されています。
The memfrob() function encrypts the first n bytes of the memory area s by exclusive-ORing each character with the number 42.
s
からn
バイトの領域に対して42をXORすることによって暗号化すると言っています。
説明は以下のように続きます。
The effect can be reversed by using memfrob() on the encrypted memory area.
Note that this function is not a proper encryption routine as the XOR constant is fixed, and is suitable only for hiding strings.
XORする値が定数なので、これは正しい暗号化ではなく、 データを隠す目的にのみ適していると言っています。
42
わざわざライブラリに入っている必要もないような関数ですが、 マジックナンバーの42が気になります。
glibcのリリースノートを見ると、次のような記述が見つかります。
* The new functions `strfry’ and `memfrob’ do mysterious and wonderful things to your strings.
mysteriousでwonderfulなことを行うと書かれています。
さらに調べると、LWNに投稿されたコメントにstrfry
とmemfrob
についての話が見つかりました。
どうやら初期の頃にジョークで追加されたものがそのまま残っているという経緯みたいですね。
42の意味ははっきりしませんが、 やはり「生命、宇宙、そして万物についての究極の疑問の答え」なのでしょうか。
使ってみる
せっかくなのでmemfrob関数を使ってみました1。
do_memfrob.c
1#define _GNU_SOURCE
2
3#include <stdio.h>
4#include <string.h>
5
6int main(void) {
7 static char buf[4096];
8 int nb = fread(buf, 1, sizeof buf, stdin);
9 memfrob(buf, nb);
10 fwrite(buf, 1, nb, stdout);
11 return 0;
12}
1行目で_GNU_SOURCE
を定義して4行目でstring.h
をインクルードしています。
標準入力から最大4096バイト読み込み、memfrob
関数を適用した結果を標準出力に書き出しています。
実行例
$ echo 'Hello, World!' | ./do_memfrob
bOFFE
}EXFN
$ echo 'Hello, World!' | ./do_memfrob | ./do_memfrob
Hello, World!
2回適用するとちゃんと元に戻ります。
-
ポータビリティの観点から、mysteriousでwonderfulなことを行いたい場面以外では、普通にforループを書くのがよいでしょう。 ↩︎