/* base64 からファイルを復元するプログラム 使い方:base64 file1 file2 file1 は base64 化された“本文”だけからなるファイルの名前です。 file2 は復元後のファイルの名前です。すでに存在すれば上書きされます。 */ #include #include /* exit() */ char buf[128+1]; char convert(char c); int main(int argc, char* argv[]) { FILE *in, *out; int i; char c, d; if (argc != 3) { fprintf(stderr, "Usage: %s file1 file2\n", argv[0]); return 1; } if ((in = fopen(argv[1], "rt")) == NULL) { fprintf(stderr, "Can't open \"%s\".\n", argv[1]); return 1; } if ((out = fopen(argv[2], "wb")) == NULL) { fprintf(stderr, "Can't open \"%s\".\n", argv[2]); fclose(in); return 1; } while (fgets(buf, 128, in)) { for (i=0; buf[i] != '\n'; i++) { if (buf[i] == '=') { /* 「=」は終わりの印。この break は for */ break; /* から抜けるだけだが、次の fgets() では */ } /* NULL が返るので while からも抜ける。 */ switch(i%4) { case 0: c = convert(buf[i]) << 2; break; case 1: d = convert(buf[i]); fputc(c | d >> 4, out); c = d << 4; break; case 2: d = convert(buf[i]); fputc(c | d >> 2, out); c = d << 6; break; case 3: d = convert(buf[i]); fputc(c | d, out); } } } fclose(out); fclose(in); return 0; } /* base64 に使われる文字を 0 から 63 までの数値に変換 */ char convert(char c) { switch(c) { case 'A': return 0; case 'B': return 1; case 'C': return 2; case 'D': return 3; case 'E': return 4; case 'F': return 5; case 'G': return 6; case 'H': return 7; case 'I': return 8; case 'J': return 9; case 'K': return 10; case 'L': return 11; case 'M': return 12; case 'N': return 13; case 'O': return 14; case 'P': return 15; case 'Q': return 16; case 'R': return 17; case 'S': return 18; case 'T': return 19; case 'U': return 20; case 'V': return 21; case 'W': return 22; case 'X': return 23; case 'Y': return 24; case 'Z': return 25; case 'a': return 26; case 'b': return 27; case 'c': return 28; case 'd': return 29; case 'e': return 30; case 'f': return 31; case 'g': return 32; case 'h': return 33; case 'i': return 34; case 'j': return 35; case 'k': return 36; case 'l': return 37; case 'm': return 38; case 'n': return 39; case 'o': return 40; case 'p': return 41; case 'q': return 42; case 'r': return 43; case 's': return 44; case 't': return 45; case 'u': return 46; case 'v': return 47; case 'w': return 48; case 'x': return 49; case 'y': return 50; case 'z': return 51; case '0': return 52; case '1': return 53; case '2': return 54; case '3': return 55; case '4': return 56; case '5': return 57; case '6': return 58; case '7': return 59; case '8': return 60; case '9': return 61; case '+': return 62; case '/': return 63; default: fprintf(stdout, "illegal character \"%c\".\n", c); exit(1); return -1; /* この return は単なる warning 封じ */ } } #if 0 ASCII コードを使うコンピュータであれば以下でも構わない。ただし 「#include 」を忘れずに。 if (isupper(c)) { return c - 'A'; } else if (islower(c)) { return c - 'a' + 26; } else if (isdigit(c)) { return c - '0' + 52; /* これはどんなコンピュータでも OK */ } else if (c == '+') { return 62; } else if (c == '/') { return 63; } else { #endif