librsync  2.0.1
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 
23 #include "config.h"
24 
25 #include <string.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 
29 #include "librsync.h"
30 
31 /*
32  * Decode a base64 string in-place - simple and slow algorithm
33  *
34  * See RFC1521 for the specification of base64.
35  */
36 size_t rs_unbase64(char *s)
37 {
38  char const *b64 =
39  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
40  int bit_offset, byte_offset, idx, i, n;
41  unsigned char *d = (unsigned char *) s;
42  char *p;
43 
44  n = i = 0;
45 
46  while (*s && (p = strchr(b64, *s))) {
47  idx = (int) (p - b64);
48  byte_offset = (i * 6) / 8;
49  bit_offset = (i * 6) % 8;
50  d[byte_offset] &= ~((1 << (8 - bit_offset)) - 1);
51  if (bit_offset < 3) {
52  d[byte_offset] |= (idx << (2 - bit_offset));
53  n = byte_offset + 1;
54  } else {
55  d[byte_offset] |= (idx >> (bit_offset - 2));
56  d[byte_offset + 1] = 0;
57  d[byte_offset + 1] |= (idx << (8 - (bit_offset - 2))) & 0xFF;
58  n = byte_offset + 2;
59  }
60  s++;
61  i++;
62  }
63 
64  return n;
65 }
66 
67 /*
68  * Encode a buffer as base64 - simple and slow algorithm.
69  */
70 void
71 rs_base64(unsigned char const *buf, int n, char *out)
72 {
73  char const *b64 =
74  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
75  int bytes, i;
76 
77  /* work out how many bytes of output there are */
78  bytes = ((n * 8) + 5) / 6;
79 
80  for (i = 0; i < bytes; i++) {
81  int byte = (i * 6) / 8;
82  int bit = (i * 6) % 8;
83 
84  if (bit < 3) {
85  if (byte >= n)
86  abort();
87  *out = b64[(buf[byte] >> (2 - bit)) & 0x3F];
88  } else {
89  if (byte + 1 == n) {
90  *out = b64[(buf[byte] << (bit - 2)) & 0x3F];
91  } else {
92  *out = b64[(buf[byte] << (bit - 2) |
93  buf[byte + 1] >> (10 - bit)) & 0x3F];
94  }
95  }
96  out++;
97  }
98  *out = 0;
99 }
100 
Public header for librsync.
size_t rs_unbase64(char *s)
Decode a base64 buffer in place.
Definition: base64.c:36
void rs_base64(unsigned char const *buf, int n, char *out)
Encode a buffer as base64.
Definition: base64.c:71