A library for a decentralised peer-to-peer chat over IPv6 only.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

lc6_base64.c 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Base64 encoding/decoding (RFC1341)
  3. * Copyright (c) 2005-2011, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "../inc/lc6_base64.h"
  12. static const unsigned char base64_table[65] =
  13. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  14. /**
  15. * base64_encode - Base64 encode
  16. * @src: Data to be encoded
  17. * @len: Length of the data to be encoded
  18. * @out_len: Pointer to output length variable, or %NULL if not used
  19. * Returns: Allocated buffer of out_len bytes of encoded data,
  20. * or %NULL on failure
  21. *
  22. * Caller is responsible for freeing the returned buffer. Returned buffer is
  23. * nul terminated to make it easier to use as a C string. The nul terminator is
  24. * not included in out_len.
  25. */
  26. unsigned char* base64_encode(const unsigned char *src, size_t len,
  27. size_t *out_len)
  28. {
  29. unsigned char *out, *pos;
  30. const unsigned char *end, *in;
  31. size_t olen;
  32. int line_len;
  33. olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
  34. olen += olen / 72; /* line feeds */
  35. olen++; /* nul termination */
  36. if (olen < len)
  37. return NULL; /* integer overflow */
  38. out = malloc(olen);
  39. if (out == NULL)
  40. return NULL;
  41. end = src + len;
  42. in = src;
  43. pos = out;
  44. line_len = 0;
  45. while (end - in >= 3) {
  46. *pos++ = base64_table[in[0] >> 2];
  47. *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
  48. *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
  49. *pos++ = base64_table[in[2] & 0x3f];
  50. in += 3;
  51. line_len += 4;
  52. if (line_len >= 72) {
  53. *pos++ = '\n';
  54. line_len = 0;
  55. }
  56. }
  57. if (end - in) {
  58. *pos++ = base64_table[in[0] >> 2];
  59. if (end - in == 1) {
  60. *pos++ = base64_table[(in[0] & 0x03) << 4];
  61. *pos++ = '=';
  62. } else {
  63. *pos++ = base64_table[((in[0] & 0x03) << 4) |
  64. (in[1] >> 4)];
  65. *pos++ = base64_table[(in[1] & 0x0f) << 2];
  66. }
  67. *pos++ = '=';
  68. line_len += 4;
  69. }
  70. if (line_len)
  71. *pos++ = '\n';
  72. *pos = '\0';
  73. if (out_len)
  74. *out_len = pos - out;
  75. return out;
  76. }
  77. /**
  78. * base64_decode - Base64 decode
  79. * @src: Data to be decoded
  80. * @len: Length of the data to be decoded
  81. * @out_len: Pointer to output length variable
  82. * Returns: Allocated buffer of out_len bytes of decoded data,
  83. * or %NULL on failure
  84. *
  85. * Caller is responsible for freeing the returned buffer.
  86. */
  87. unsigned char * base64_decode(const unsigned char *src, size_t len,
  88. size_t *out_len)
  89. {
  90. unsigned char dtable[256], *out, *pos, block[4], tmp;
  91. size_t i, count, olen;
  92. int pad = 0;
  93. memset(dtable, 0x80, 256);
  94. for (i = 0; i < sizeof(base64_table) - 1; i++)
  95. dtable[base64_table[i]] = (unsigned char) i;
  96. dtable['='] = 0;
  97. count = 0;
  98. for (i = 0; i < len; i++) {
  99. if (dtable[src[i]] != 0x80)
  100. count++;
  101. }
  102. if (count == 0 || count % 4)
  103. return NULL;
  104. olen = count / 4 * 3;
  105. pos = out = malloc(olen);
  106. if (out == NULL)
  107. return NULL;
  108. count = 0;
  109. for (i = 0; i < len; i++) {
  110. tmp = dtable[src[i]];
  111. if (tmp == 0x80)
  112. continue;
  113. if (src[i] == '=')
  114. pad++;
  115. block[count] = tmp;
  116. count++;
  117. if (count == 4) {
  118. *pos++ = (block[0] << 2) | (block[1] >> 4);
  119. *pos++ = (block[1] << 4) | (block[2] >> 2);
  120. *pos++ = (block[2] << 6) | block[3];
  121. count = 0;
  122. if (pad) {
  123. if (pad == 1)
  124. pos--;
  125. else if (pad == 2)
  126. pos -= 2;
  127. else {
  128. /* Invalid padding */
  129. free(out);
  130. return NULL;
  131. }
  132. break;
  133. }
  134. }
  135. }
  136. *out_len = pos - out;
  137. return out;
  138. }