File: base64.c

package info (click to toggle)
screem 0.2.1-1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 3,748 kB
  • ctags: 2,270
  • sloc: ansic: 26,366; sh: 7,453; makefile: 512; sed: 93; perl: 18
file content (100 lines) | stat: -rw-r--r-- 2,957 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/* 
   Text->Base64 convertion, from RFC1521
   Copyright (C) 1998-99, Joe Orton <joe@orton.demon.co.uk>
                                                                     
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
  
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
  
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   
   $Id: base64.c,v 1.1.1.1 1999/11/21 19:46:54 davek Exp $
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include "base64.h"

/* Base64 specification from RFC 1521 */

const char b64_alphabet[65] = { 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz"
    "0123456789+/=" };
    
char *base64( const char *text ) {
    /* The tricky thing about this is doing the padding at the end,
     * doing the bit manipulation requires a bit of concentration only */
    char *buffer, *point;
    int inlen, outlen;
    
    /* Use 'buffer' to store the output. Work out how big it should be...
     * This must be a multiple of 4 bytes */

    inlen = strlen( text );
    outlen = (inlen*4)/3;
    if( (inlen % 3) > 0 ) /* got to pad */
	outlen += 4 - (inlen % 3);
    
    buffer = malloc( outlen + 1 ); /* +1 for the \0 */
    
    /* now do the main stage of conversion, 3 bytes at a time,
     * leave the trailing bytes (if there are any) for later */

    for( point=buffer; inlen>=3; inlen-=3, text+=3 ) {
	*(point++) = b64_alphabet[ (*text)>>2 ]; 
	*(point++) = b64_alphabet[ ((*text)<<4 & 0x30) | (*(text+1))>>4 ]; 
	*(point++) = b64_alphabet[ ((*(text+1))<<2 & 0x3c) | (*(text+2))>>6 ];
	*(point++) = b64_alphabet[ (*(text+2)) & 0x3f ];
    }

    /* Now deal with the trailing bytes */
    if( inlen ) {
	/* We always have one trailing byte */
	*(point++) = b64_alphabet[ (*text)>>2 ];
	*(point++) = b64_alphabet[ ( ((*text)<<4 & 0x30) |
				     (inlen==2?(*(text+1))>>4:0) ) ]; 
	*(point++) = (inlen==1?'=':b64_alphabet[ (*(text+1))<<2 & 0x3c ] );
	*(point++) = '=';
    }

    /* Null-terminate */
    *point = '\0';

    return buffer;
}

#ifdef BASE64_TEST

/* Standalone tester */

#include <stdio.h>

/* Tester for Base64 algorithm */
int main( int argc, char **argv ) {
    char *out;
    if( argc != 2 ) {
	printf( "Usage: %s plaintext\n", argv[0] );
	exit(-1);
    }
    out = base64( argv[1] );
    printf( "Plain: [%s], Base64: [%s]\n", argv[1], out );
    return 0;
}

#endif /* BASE64_TEST */