Created
September 8, 2010 00:28
-
-
Save atr000/569384 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
\cfg{man-identity}{base64}{1}{2004-11-20}{Simon Tatham}{Simon Tatham} | |
\title Man page for \cw{base64} | |
\U NAME | |
\cw{base64} - stand-alone encoder and decoder for base64 | |
\U SYNOPSIS | |
\c base64 [ -d ] [ filename ] | |
\e bbbbbb bb iiiiiiii | |
\c base64 -e [ -c width ] [ filename ] | |
\e bbbbbb bb bb iiiii iiiiiiii | |
\U DESCRIPTION | |
\cw{base64} is a command-line utility for encoding and decoding the | |
\q{base64} encoding. | |
This encoding, defined in | |
\W{http://www.ietf.org/rfc/rfc2045.txt}{RFC 2045}, is primarily used | |
to encode binary attachments in MIME e-mail, but is widely used in | |
many other applications as well. For example, the \q{Content-MD5} | |
mail header contains a small piece of base64; SSH private keys are | |
generally stored as base64-encoded blobs; and so on. | |
Other utilities, such as \cw{munpack}, exist which will take an | |
entire MIME-encoded message, identify the base64-encoded subparts, | |
and decode them. However, these utilities will not help you if you | |
need to inspect a Content-MD5 header or an SSH private key. | |
\cw{base64} is a very simple stand-alone encoder and decoder for the | |
base64 format \e{alone}. It does not try to understand MIME headers | |
or anything other than raw data. | |
\U OPTIONS | |
By default (if neither \cw{-d} or \cw{-e} is supplied), \cw{base64} | |
operates in decode mode. | |
\dt \cw{-d} | |
\dd Places \cw{base64} into decode mode. In this mode, it will read | |
from standard input or the supplied file name, ignore all characters | |
that are not part of the base64 alphabet, decode the ones that are, | |
and output the decoded data on standard output. | |
\dt \cw{-e} | |
\dd Places \cw{base64} into encode mode. In this mode, it will read | |
binary data from standard input or the supplied file name, encode it | |
as base64, and output the encoded data on standard output. | |
\dt \cw{-c} \e{width} | |
\dd If \cw{base64} is operating in encode mode, this controls the | |
number of base64 characters output per line of the encoded file. | |
Normally base64-reading applications do not care about this, so the | |
default of 64 characters per line is perfectly adequate. | |
\lcont{ | |
The special value 0 will prevent \cw{base64} from ever writing a | |
line break in the middle of the data at all. | |
The base64 encoding converts between a group of three plaintext | |
bytes and a group of four encoded bytes. \cw{base64} does not | |
support breaking an encoded group across a line (although it can | |
handle it as input if it receives it). Therefore, the \e{width} | |
parameter passed to \cw{-c} must be a multiple of 4. | |
} | |
\U LICENCE | |
\cw{base64} is free software, distributed under the MIT licence. | |
Type \cw{base64 --licence} to see the full licence text. | |
\versionid $Id$ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#define isbase64(c) ( ((c) >= 'A' && (c) <= 'Z') || \ | |
((c) >= 'a' && (c) <= 'z') || \ | |
((c) >= '0' && (c) <= '9') || \ | |
(c) == '+' || (c) == '/' || (c) == '=' \ | |
) | |
int base64_decode_atom(char *atom, unsigned char *out) { | |
int vals[4]; | |
int i, v, len; | |
unsigned word; | |
char c; | |
for (i = 0; i < 4; i++) { | |
c = atom[i]; | |
if (c >= 'A' && c <= 'Z') | |
v = c - 'A'; | |
else if (c >= 'a' && c <= 'z') | |
v = c - 'a' + 26; | |
else if (c >= '0' && c <= '9') | |
v = c - '0' + 52; | |
else if (c == '+') | |
v = 62; | |
else if (c == '/') | |
v = 63; | |
else if (c == '=') | |
v = -1; | |
else | |
return 0; /* invalid atom */ | |
vals[i] = v; | |
} | |
if (vals[0] == -1 || vals[1] == -1) | |
return 0; | |
if (vals[2] == -1 && vals[3] != -1) | |
return 0; | |
if (vals[3] != -1) | |
len = 3; | |
else if (vals[2] != -1) | |
len = 2; | |
else | |
len = 1; | |
word = ((vals[0] << 18) | | |
(vals[1] << 12) | | |
((vals[2] & 0x3F) << 6) | | |
(vals[3] & 0x3F)); | |
out[0] = (word >> 16) & 0xFF; | |
if (len > 1) | |
out[1] = (word >> 8) & 0xFF; | |
if (len > 2) | |
out[2] = word & 0xFF; | |
return len; | |
} | |
void base64_encode_atom(unsigned char *data, int n, char *out) { | |
static const char base64_chars[] = | |
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
unsigned word; | |
word = data[0] << 16; | |
if (n > 1) | |
word |= data[1] << 8; | |
if (n > 2) | |
word |= data[2]; | |
out[0] = base64_chars[(word >> 18) & 0x3F]; | |
out[1] = base64_chars[(word >> 12) & 0x3F]; | |
if (n > 1) | |
out[2] = base64_chars[(word >> 6) & 0x3F]; | |
else | |
out[2] = '='; | |
if (n > 2) | |
out[3] = base64_chars[word & 0x3F]; | |
else | |
out[3] = '='; | |
} | |
const char usagemsg[] = | |
"usage: base64 [-d] [filename] decode from a file or from stdin\n" | |
" or: base64 -e [-cNNN] [filename] encode from a file or from stdin\n" | |
"where: -d decode mode (default)\n" | |
" -e encode mode\n" | |
" -cNNN set number of chars per line for encoded output\n" | |
" also: base64 --version report version number\n" | |
" base64 --help display this help text\n" | |
" base64 --licence display the (MIT) licence text\n" | |
; | |
void usage(void) { | |
fputs(usagemsg, stdout); | |
} | |
const char licencemsg[] = | |
"base64 is copyright 2001,2004 Simon Tatham.\n" | |
"\n" | |
"Permission is hereby granted, free of charge, to any person\n" | |
"obtaining a copy of this software and associated documentation files\n" | |
"(the \"Software\"), to deal in the Software without restriction,\n" | |
"including without limitation the rights to use, copy, modify, merge,\n" | |
"publish, distribute, sublicense, and/or sell copies of the Software,\n" | |
"and to permit persons to whom the Software is furnished to do so,\n" | |
"subject to the following conditions:\n" | |
"\n" | |
"The above copyright notice and this permission notice shall be\n" | |
"included in all copies or substantial portions of the Software.\n" | |
"\n" | |
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n" | |
"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n" | |
"MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n" | |
"NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\n" | |
"BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\n" | |
"ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n" | |
"CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n" | |
"SOFTWARE.\n" | |
; | |
void licence(void) { | |
fputs(licencemsg, stdout); | |
} | |
void version(void) { | |
#define SVN_REV "$Revision$" | |
char rev[sizeof(SVN_REV)]; | |
char *p, *q; | |
strcpy(rev, SVN_REV); | |
for (p = rev; *p && *p != ':'; p++); | |
if (*p) { | |
p++; | |
while (*p && isspace(*p)) p++; | |
for (q = p; *q && *q != '$'; q++); | |
if (*q) *q = '\0'; | |
printf("base64 revision %s\n", p); | |
} else { | |
printf("base64: unknown version\n"); | |
} | |
} | |
int main(int ac, char **av) { | |
int encoding = 0; | |
int cpl = 64; | |
FILE *fp; | |
char *fname; | |
char *eptr; | |
fname = NULL; | |
while (--ac) { | |
char *v, *p = *++av; | |
if (*p == '-') { | |
while (*p) { | |
char c = *++p; | |
switch (c) { | |
case '-': | |
p++; | |
if (!strcmp(p, "version")) { | |
version(); | |
exit(0); | |
} else if (!strcmp(p, "help")) { | |
usage(); | |
exit(0); | |
} else if (!strcmp(p, "licence") || | |
!strcmp(p, "license")) { | |
licence(); | |
exit(0); | |
} else { | |
fprintf(stderr, "base64: unknown long option '--%s'\n", | |
p); | |
exit(1); | |
} | |
break; | |
case 'v': | |
case 'V': | |
version(); | |
exit(0); | |
break; | |
case 'h': | |
case 'H': | |
usage(); | |
exit(0); | |
break; | |
case 'd': | |
encoding = 0; | |
break; | |
case 'e': | |
encoding = 1; | |
break; | |
case 'c': | |
/* | |
* Options requiring values. | |
*/ | |
v = p+1; | |
if (!*v && ac > 1) { | |
--ac; | |
v = *++av; | |
} | |
if (!*v) { | |
fprintf(stderr, "base64: option '-%c' expects" | |
" an argument\n", c); | |
exit(1); | |
} | |
switch (c) { | |
case 'c': | |
cpl = strtol(v, &eptr, 10); | |
if (eptr && *eptr) { | |
fprintf(stderr, "base64: option -c expects" | |
" a numeric argument\n"); | |
exit(1); | |
} | |
if (cpl % 4) { | |
fprintf(stderr, "base64: chars per line should be" | |
" divisible by 4\n"); | |
exit(1); | |
} | |
break; | |
} | |
p = ""; | |
break; | |
} | |
} | |
} else { | |
if (!fname) | |
fname = p; | |
else { | |
fprintf(stderr, "base64: expected only one filename\n"); | |
exit(0); | |
} | |
} | |
} | |
if (fname) { | |
fp = fopen(fname, encoding ? "rb" : "r"); | |
if (!fp) { | |
fprintf(stderr, "base64: unable to open '%s': %s\n", fname, | |
strerror(errno)); | |
exit(1); | |
} | |
} else | |
fp = stdin; | |
if (encoding) { | |
unsigned char in[3]; | |
char out[4]; | |
int column; | |
int n; | |
column = 0; | |
while (1) { | |
if (cpl && column >= cpl) { | |
putchar('\n'); | |
column = 0; | |
} | |
n = fread(in, 1, 3, fp); | |
if (n == 0) break; | |
base64_encode_atom(in, n, out); | |
fwrite(out, 1, 4, stdout); | |
column += 4; | |
} | |
putchar('\n'); | |
} else { | |
char in[4]; | |
unsigned char out[3]; | |
int c, i, n, eof; | |
eof = 0; | |
do { | |
for (i = 0; i < 4; i++) { | |
do { | |
c = fgetc(fp); | |
} while (c != EOF && !isbase64(c)); | |
if (c == EOF) { | |
eof = 1; | |
break; | |
} | |
in[i] = c; | |
} | |
if (i > 0) { | |
if (i < 4) { | |
fprintf(stderr, "base64: warning: number of base64" | |
" characters was not a multiple of 4\n"); | |
while (i < 4) in[i++] = '='; | |
} | |
n = base64_decode_atom(in, out); | |
fwrite(out, 1, n, stdout); | |
} | |
} while (!eof); | |
} | |
if (fname) | |
fclose(fp); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# for `make release' and `make html' | |
DESTDIR = . | |
# for `make install' | |
PREFIX = /usr/local | |
BINDIR = $(PREFIX)/bin | |
SCRIPTDIR = $(PREFIX)/bin | |
MANDIR = $(PREFIX)/man/man1 | |
INSTALL = install | |
IPROG =# flags for installing programs (default none) | |
IDATA = -m 0644 # flags for installing data | |
all: base64.1 base64 | |
progs: base64 | |
man: base64.1 | |
base64: base64.c | |
$(CC) $(CFLAGS) -o $@ $< | |
%.1: %.but | |
halibut --man=$@ $< | |
clean: | |
rm -f *.1 base64 *.html *.tar.gz | |
html: | |
halibut --html=base64.html base64.but | |
mv base64.html $(DESTDIR) | |
release: base64.1 | |
mkdir -p reltmp/base64 | |
ln -s ../../base64.c reltmp/base64 | |
ln -s ../../base64.1 reltmp/base64 | |
ln -s ../../base64.but reltmp/base64 | |
ln -s ../../Makefile reltmp/base64 | |
tar -C reltmp -chzf $(DESTDIR)/base64.tar.gz base64 | |
rm -rf reltmp | |
install: install-progs install-man | |
install-progs: base64 | |
mkdir -p $(BINDIR) | |
$(INSTALL) $(IPROG) base64 $(BINDIR)/base64 | |
install-man: base64.1 | |
mkdir -p $(MANDIR) | |
$(INSTALL) $(IDATA) base64.1 $(MANDIR)/base64.1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment