2
0

conversion.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*
  2. * $Id$
  3. *
  4. * Copyright (C) 2012 Smile Communications, [email protected]
  5. * Copyright (C) 2012 Smile Communications, [email protected]
  6. *
  7. * The initial version of this code was written by Dragos Vingarzan
  8. * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
  9. * Fruanhofer Institute. It was and still is maintained in a separate
  10. * branch of the original SER. We are therefore migrating it to
  11. * Kamailio/SR and look forward to maintaining it from here on out.
  12. * 2011/2012 Smile Communications, Pty. Ltd.
  13. * ported/maintained/improved by
  14. * Jason Penton (jason(dot)penton(at)smilecoms.com and
  15. * Richard Good (richard(dot)good(at)smilecoms.com) as part of an
  16. * effort to add full IMS support to Kamailio/SR using a new and
  17. * improved architecture
  18. *
  19. * NB: Alot of this code was originally part of OpenIMSCore,
  20. * FhG Fokus.
  21. * Copyright (C) 2004-2006 FhG Fokus
  22. * Thanks for great work! This is an effort to
  23. * break apart the various CSCF functions into logically separate
  24. * components. We hope this will drive wider use. We also feel
  25. * that in this way the architecture is more complete and thereby easier
  26. * to manage in the Kamailio/SR environment
  27. *
  28. * This file is part of Kamailio, a free SIP server.
  29. *
  30. * Kamailio is free software; you can redistribute it and/or modify
  31. * it under the terms of the GNU General Public License as published by
  32. * the Free Software Foundation; either version 2 of the License, or
  33. * (at your option) any later version
  34. *
  35. * Kamailio is distributed in the hope that it will be useful,
  36. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  37. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  38. * GNU General Public License for more details.
  39. *
  40. * You should have received a copy of the GNU General Public License
  41. * along with this program; if not, write to the Free Software
  42. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  43. *
  44. */
  45. /**
  46. * \file
  47. *
  48. * Serving-CSCF - Conversion between base16, base64 and base256
  49. *
  50. * \author Dragos Vingarzan vingarzan -at- fokus dot fraunhofer dot de
  51. *
  52. */
  53. /** base16 char constants */
  54. char *hexchars="0123456789abcdef";
  55. /**
  56. * Converts a binary encoded value to its base16 representation.
  57. * @param from - buffer containing the input data
  58. * @param len - the size of from
  59. * @param to - the output buffer !!! must have at least len*2 allocated memory
  60. * @returns the written length
  61. */
  62. int bin_to_base16(char *from,int len, char *to)
  63. {
  64. int i,j;
  65. for(i=0,j=0;i<len;i++,j+=2){
  66. to[j] = hexchars[(((unsigned char)from[i]) >>4 )&0x0F];
  67. to[j+1] = hexchars[(((unsigned char)from[i]))&0x0F];
  68. }
  69. return 2*len;
  70. }
  71. /** from base16 char to int */
  72. #define HEX_DIGIT(x) \
  73. ((x>='0'&&x<='9')?x-'0':((x>='a'&&x<='f')?x-'a'+10:((x>='A'&&x<='F')?x-'A'+10:0)))
  74. /**
  75. * Converts a hex encoded value to its binary value
  76. * @param from - buffer containing the input data
  77. * @param len - the size of from
  78. * @param to - the output buffer !!! must have at least len/2 allocated memory
  79. * @returns the written length
  80. */
  81. int base16_to_bin(char *from,int len, char *to)
  82. {
  83. int i,j;
  84. for(i=0,j=0;j<len;i++,j+=2){
  85. to[i] = (unsigned char) ( HEX_DIGIT(from[j])<<4 | HEX_DIGIT(from[j+1]));
  86. }
  87. return i;
  88. }
  89. /**
  90. * Convert on character from base64 encoding to integer.
  91. *"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  92. * @param x - characted to convert
  93. * @returns the int value or -1 if terminal character ('=')
  94. */
  95. static inline int base64_val(char x)\
  96. {
  97. switch(x){
  98. case '=': return -1;
  99. case 'A': return 0;
  100. case 'B': return 1;
  101. case 'C': return 2;
  102. case 'D': return 3;
  103. case 'E': return 4;
  104. case 'F': return 5;
  105. case 'G': return 6;
  106. case 'H': return 7;
  107. case 'I': return 8;
  108. case 'J': return 9;
  109. case 'K': return 10;
  110. case 'L': return 11;
  111. case 'M': return 12;
  112. case 'N': return 13;
  113. case 'O': return 14;
  114. case 'P': return 15;
  115. case 'Q': return 16;
  116. case 'R': return 17;
  117. case 'S': return 18;
  118. case 'T': return 19;
  119. case 'U': return 20;
  120. case 'V': return 21;
  121. case 'W': return 22;
  122. case 'X': return 23;
  123. case 'Y': return 24;
  124. case 'Z': return 25;
  125. case 'a': return 26;
  126. case 'b': return 27;
  127. case 'c': return 28;
  128. case 'd': return 29;
  129. case 'e': return 30;
  130. case 'f': return 31;
  131. case 'g': return 32;
  132. case 'h': return 33;
  133. case 'i': return 34;
  134. case 'j': return 35;
  135. case 'k': return 36;
  136. case 'l': return 37;
  137. case 'm': return 38;
  138. case 'n': return 39;
  139. case 'o': return 40;
  140. case 'p': return 41;
  141. case 'q': return 42;
  142. case 'r': return 43;
  143. case 's': return 44;
  144. case 't': return 45;
  145. case 'u': return 46;
  146. case 'v': return 47;
  147. case 'w': return 48;
  148. case 'x': return 49;
  149. case 'y': return 50;
  150. case 'z': return 51;
  151. case '0': return 52;
  152. case '1': return 53;
  153. case '2': return 54;
  154. case '3': return 55;
  155. case '4': return 56;
  156. case '5': return 57;
  157. case '6': return 58;
  158. case '7': return 59;
  159. case '8': return 60;
  160. case '9': return 61;
  161. case '+': return 62;
  162. case '/': return 63;
  163. }
  164. return 0;
  165. }
  166. /**
  167. * Convert a string encoded in base64 to binary value.
  168. * @param from - buffer containing the input data
  169. * @param from_len - the size of from
  170. * @param to - the output buffer !!! must have at least len*2 allocated memory
  171. * @returns the written length
  172. */
  173. int base64_to_bin(char *from,int from_len, char *to)
  174. {
  175. int i,j,x1,x2,x3,x4;
  176. for(i=0,j=0;i<from_len;i+=4){
  177. x1=base64_val(from[i]);
  178. x2=base64_val(from[i+1]);
  179. x3=base64_val(from[i+2]);
  180. x4=base64_val(from[i+3]);
  181. to[j++]=(x1<<2) | ((x2 & 0x30)>>4);
  182. if (x3==-1) break;
  183. to[j++]=((x2 & 0x0F)<<4) | ((x3 & 0x3C)>>2);
  184. if (x4==-1) break;
  185. to[j++]=((x3 & 0x03)<<6) | (x4 & 0x3F);
  186. }
  187. return j;
  188. }
  189. /** base64 characters constant */
  190. char base64[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  191. /**
  192. * Convert a binary string to base64 encoding.
  193. * @param src - the source buffer
  194. * @param src_len - length of the source buffer
  195. * @param ptr - the destination buffer - must be allocated to at least src_len/3*4+4
  196. * @returns the length of the resulted buffer
  197. */
  198. int bin_to_base64(char *src,int src_len,char* ptr)
  199. {
  200. int i,k;
  201. int triplets,rest;
  202. char *s;
  203. s=ptr;
  204. triplets = src_len/3;
  205. rest = src_len%3;
  206. for(i=0;i<triplets*3;i+=3){
  207. k = (((unsigned char) src[i])&0xFC)>>2;
  208. *ptr=base64[k];ptr++;
  209. k = (((unsigned char) src[i])&0x03)<<4;
  210. k |=(((unsigned char) src[i+1])&0xF0)>>4;
  211. *ptr=base64[k];ptr++;
  212. k = (((unsigned char) src[i+1])&0x0F)<<2;
  213. k |=(((unsigned char) src[i+2])&0xC0)>>6;
  214. *ptr=base64[k];ptr++;
  215. k = (((unsigned char) src[i+2])&0x3F);
  216. *ptr=base64[k];ptr++;
  217. }
  218. i=triplets*3;
  219. switch(rest){
  220. case 0:
  221. break;
  222. case 1:
  223. k = (((unsigned char) src[i])&0xFC)>>2;
  224. *ptr=base64[k];ptr++;
  225. k = (((unsigned char) src[i])&0x03)<<4;
  226. *ptr=base64[k];ptr++;
  227. *ptr='=';ptr++;
  228. *ptr='=';ptr++;
  229. break;
  230. case 2:
  231. k = (((unsigned char) src[i])&0xFC)>>2;
  232. *ptr=base64[k];ptr++;
  233. k = (((unsigned char) src[i])&0x03)<<4;
  234. k |=(((unsigned char) src[i+1])&0xF0)>>4;
  235. *ptr=base64[k];ptr++;
  236. k = (((unsigned char) src[i+1])&0x0F)<<2;
  237. *ptr=base64[k];ptr++;
  238. *ptr='=';ptr++;
  239. break;
  240. }
  241. return ptr-s;
  242. }