あなたの blog に隠しメッセージを

ある文章を変換して、実行すると元の文章を出力する Whitespace プログラムを作るプログラムを作ってみました。(Whitespace についての説明は Whitespace - Wikipedia あたりを読んでください)

使い方

プログラムに引数が無い時は、標準入力からファイルを読み込み、標準出力から Whitespace のプログラムを吐き出します。

> echo あいうえお | ./a.out > hoge.ws
> perl whitespace.pl hoge.ws
あいうえお
>

プログラムに引数がある時は、引数を名前とするファイルを読み、ファイル名.ws という名前のファイルに出力します。

> cat fuga
いろは
> ./a.out fuga
> perl whitespace.pl fuga.ws
いろは
>

ファイルサイズは 十数倍程度になります。
エンディアンが違うとうまくいかないかもしれません。

使い道

このプログラムを利用すると、文章中に Whitespace で書かれた隠しメッセージを仕込むことができます。誰にも知られないように誰かを罵倒したい、釣り文章のアリバイ(←誤用かな)を用意したい、といった方に最適です。

C言語 (Whitespace じゃなくてすみません) のソース

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>

void push_char(unsigned char c, FILE *fout)
{
    int i=7;
    fputs("   ",fout);
    while(i>0 && (c>>i &1)==0)
        i--;
    while(i>=0){
        if(c>>i & 1)
            putc('\t',fout);
        else
            putc(' ',fout);
        i--;
    }
    putc('\n',fout);
    return;
}

void translate(FILE *fin,FILE *fout)
{
    int c;

    while((c=fgetc(fin))!=EOF){
        push_char(c,fout);
        fputs("\t\n  ",fout);
    }
    fputs("\n\n\n",fout);
    return;
}

FILE *open_file_add_extension(char *inputfilename, char *extension, char *mode)
{
    int len;
    char *foutname;
    FILE *fout;

    len = strlen(inputfilename)+strlen(extension)+1;
    if((foutname=malloc(sizeof(char)*(len)))==NULL){
        perror("");
        return NULL;
    }else{
        snprintf(foutname,len,"%s%s",inputfilename,extension);
        if((fout=fopen(foutname,mode))==NULL){
            perror(foutname);
        }
        free(foutname);
        return fout;
    }
}

int main(int argc, char *argv[])
{
    int i;
    FILE *fin,*fout;

    setlocale(LC_ALL,"");
    if(argc<2)
        translate(stdin,stdout);
    else
        for(i=1;i<argc;i++){
            if((fin=fopen(argv[i],"r"))==NULL){
                perror(argv[i]);
                continue;
            }
            if((fout=open_file_add_extension(argv[i],".ws","w"))==NULL){
                fclose(fin);
                continue;
            }
            translate(fin,fout);
            fclose(fout);
            fclose(fin);
        }
    return 0;
}