librsync  2.3.3
base64.c
1/*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 *
3 * librsync -- the library for network deltas
4 *
5 * Copyright (C) 2000 by Martin Pool <mbp@sourcefrog.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <stdlib.h>
23#include <string.h>
24#include "librsync.h"
25
26/** Decode a base64 string in-place - simple and slow algorithm.
27 *
28 * See RFC1521 for the specification of base64. */
29size_t rs_unbase64(char *s)
30{
31 char const *b64 =
32 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
33 int bit_offset, byte_offset, idx, i, n;
34 unsigned char *d = (unsigned char *)s;
35 char *p;
36
37 n = i = 0;
38
39 while (*s && (p = strchr(b64, *s))) {
40 idx = (int)(p - b64);
41 byte_offset = (i * 6) / 8;
42 bit_offset = (i * 6) % 8;
43 d[byte_offset] &= (unsigned char)~((1 << (8 - bit_offset)) - 1);
44 if (bit_offset < 3) {
45 d[byte_offset] |= (unsigned char)(idx << (2 - bit_offset));
46 n = byte_offset + 1;
47 } else {
48 d[byte_offset] |= (unsigned char)(idx >> (bit_offset - 2));
49 d[byte_offset + 1] = (unsigned char)(idx << (8 - (bit_offset - 2)));
50 n = byte_offset + 2;
51 }
52 s++;
53 i++;
54 }
55 return n;
56}
57
58/** Encode a buffer as base64 - simple and slow algorithm. */
59void rs_base64(unsigned char const *buf, int n, char *out)
60{
61 char const *b64 =
62 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
63 int bytes, i;
64
65 /* work out how many bytes of output there are */
66 bytes = ((n * 8) + 5) / 6;
67
68 for (i = 0; i < bytes; i++) {
69 int byte = (i * 6) / 8;
70 int bit = (i * 6) % 8;
71
72 if (bit < 3) {
73 if (byte >= n)
74 abort();
75 *out = b64[(buf[byte] >> (2 - bit)) & 0x3F];
76 } else {
77 if (byte + 1 == n) {
78 *out = b64[(buf[byte] << (bit - 2)) & 0x3F];
79 } else {
80 *out =
81 b64[(buf[byte] << (bit - 2) | buf[byte + 1] >> (10 - bit)) &
82 0x3F];
83 }
84 }
85 out++;
86 }
87 *out = 0;
88}
Public header for librsync.