Advertisement
teknoraver

base64

Apr 14th, 2016
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.35 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdint.h>
  3.  
  4. /* base64 charset for fast encoding */
  5. static const uint8_t enc_ch[] =
  6.     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  7.  
  8. /* decode charset */
  9. static const uint8_t dec_ch[] = {
  10.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  11.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  12.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
  13.     52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0,
  14.     0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  15.     15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
  16.     0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  17.     41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
  18. };
  19.  
  20. static void b64enc_block(uint8_t *in, uint8_t *out, size_t len)
  21. {
  22.     out[0] = enc_ch[in[0] >> 2];
  23.     out[1] = enc_ch[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)];
  24.     out[2] = len > 1 ? enc_ch[((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6)] : '=';
  25.     out[3] = len > 2 ? enc_ch[in[2] & 0x3f] : '=';
  26. }
  27.  
  28. static void b64dec_block(uint8_t *in, uint8_t *out)
  29. {
  30.     out[0] = dec_ch[in[0]] << 2 | dec_ch[in[1]] >> 4;
  31.     out[1] = dec_ch[in[1]] << 4 | dec_ch[in[2]] >> 2;
  32.     out[2] = ((dec_ch[in[2]] << 6) & 0xc0) | dec_ch[in[3]];
  33. }
  34.  
  35. int b64enc(uint8_t *in, uint8_t *out, size_t len)
  36. {
  37.     int i, o;
  38.     for(i = 0, o = 0; i < len; i += 3, o += 4)
  39.         b64enc_block(in + i, out + o, len - i);
  40.     return o;
  41. }
  42.  
  43. int b64dec(uint8_t *in, uint8_t *out, size_t len)
  44. {
  45.     int i, o;
  46.     for(i = 0, o = 0; i < len; i += 4, o += 3)
  47.         b64dec_block(in + i, out + o);
  48.     return o;
  49. }
  50.  
  51. #ifdef STANDALONE
  52.  
  53. /* simple main to test the functions */
  54. int main(int argc, char *argv[])
  55. {
  56.     /* usually base64 text is formatted in 76 characters line so
  57.      * every 57 input bytes we get 76 characters (57 / 3 * 4 = 76)
  58.      */
  59.     uint8_t dec[58];
  60.     uint8_t enc[77];
  61.     size_t len;
  62.  
  63.     if(argc != 2 || argv[1][0] != '-' || (argv[1][1] != 'd' && argv[1][1] != 'e')) {
  64.         fprintf(stderr, "usage: %s [-e|-d]\n", *argv);
  65.         return 1;
  66.     }
  67.  
  68.     if(argv[1][1] == 'e')
  69.         while((len = fread(dec, 1, 57, stdin))) {
  70.             len = b64enc(dec, enc, len);
  71.             enc[len] = 0;
  72.             puts((char *)enc);
  73.         }
  74.     else
  75.         while((len = fread(enc, 1, 76, stdin))) {
  76.             len = b64dec(enc, dec, len);
  77.             dec[len] = 0;
  78.             fputs((char *)dec, stdout);
  79.             /* skip the \n */
  80.             if(!fread(enc, 1, 1, stdin))
  81.                 return 0;
  82.         }
  83.  
  84.     fclose(stdin);
  85.     fclose(stdout);
  86.     return 0;
  87. }
  88.  
  89. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement