2 Copyright © 2013 Alastair Stuart
4 This program is open source software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
25 #define VERSION "0.01"
27 const char base64_table
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
28 const int padding_table
[] = {0, 2, 1};
30 void base64_encode_block(uint8_t in
[3], char out
[5])
32 uint8_t octet_a
= in
[0];
33 uint8_t octet_b
= in
[1];
34 uint8_t octet_c
= in
[2];
36 uint32_t combined
= (octet_a
<< 16) + (octet_b
<< 8) + octet_c
;
38 out
[0] = base64_table
[(combined
>> 3 * 6) & 0x3F];
39 out
[1] = base64_table
[(combined
>> 2 * 6) & 0x3F];
40 out
[2] = base64_table
[(combined
>> 1 * 6) & 0x3F];
41 out
[3] = base64_table
[(combined
>> 0 * 6) & 0x3F];
45 void usage(char* program
)
47 printf("Usage: %s [options] [file]\n", program
);
48 printf("Encodes a file into base64..\n"
50 " -w, --wrap [num] Wrap lines after [num] characters.\n"
52 " --help Print this message.\n"
53 " --version Show version info.\n");
56 int main(int argc
, char* argv
[])
58 size_t line_width
= 0;
60 static struct option long_options
[] = {
61 {"wrap", required_argument
, NULL
, 'w'},
62 {"help", no_argument
, NULL
, 1},
63 {"version", no_argument
, NULL
, 2},
68 while ((c
= getopt_long(argc
, argv
, "w:",
69 long_options
, NULL
)) != -1)
74 // check if wrap argument is a valid number
75 for (size_t i
= 0; i
< strlen(optarg
); i
++)
77 if (!isdigit(optarg
[i
])) {
78 fprintf(stderr
, "%s: invalid wrap size: %s\n",
89 printf("base64 (mutos) v"VERSION
"\n");
92 printf("Run '%s --help' for usage.\n",
99 char* filename
= NULL
;
101 if ((argc
- optind
) > 1) {
102 fprintf(stderr
, "%s: extra operand: %s\n",
103 argv
[0], argv
[optind
+1]);
105 } else if ((argc
- optind
) < 1) {
109 input
= fopen(argv
[optind
], "rb");
110 filename
= argv
[optind
];
114 fprintf(stderr
, "%s: %s: %s\n",
115 argv
[0], strerror(errno
), filename
);
119 bool last_block
= false;
128 uint8_t block
[3] = {0};
129 block
[0] = (c
= fgetc(input
)) != EOF
? c
: 0;
130 if (c
!= EOF
) { length
++; } else { eof_count
++; }
131 block
[1] = (c
= fgetc(input
)) != EOF
? c
: 0;
132 if (c
!= EOF
) { length
++; } else { eof_count
++; }
133 block
[2] = (c
= fgetc(input
)) != EOF
? c
: 0;
134 if (c
!= EOF
) { length
++; } else { eof_count
++; }
140 if (eof_count
== 3) {
144 char encoded
[5] = {'\0'};
145 base64_encode_block(block
, encoded
);
148 for (int i
= 0; i
< padding_table
[length
% 3]; i
++)
154 for (size_t i
= 0; i
< 4; i
++)
156 printf("%c", encoded
[i
]);
159 if (line_width
% wrap
== 0) {