basex.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. /*
  2. * convert/decode to/from ascii using various bases
  3. *
  4. * Copyright (C) 2008 iptelorg GmbH
  5. *
  6. * Permission to use, copy, modify, and distribute this software for any
  7. * purpose with or without fee is hereby granted, provided that the above
  8. * copyright notice and this permission notice appear in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. /*!
  19. * \file
  20. * \brief Kamailio core :: convert/decode to/from ascii using various bases
  21. *
  22. * Copyright (C) 2008 iptelorg GmbH
  23. * \ingroup core
  24. *
  25. * Module: \ref core
  26. *
  27. *
  28. * Functions:
  29. * - base16_enc(src, src_len, dst, dst_len) : encode to standard hex
  30. * - base16_dec(src, src_len, dst, dst_len) : decode from standard hex
  31. * - base16_enc_len(len) : length needed to encode len bytes (macro)
  32. * - base16_max_dec_len(len) : length needed to decode a string of size len
  33. *
  34. * - base64_enc(src, src_len, dst, dst_len) : encode to base64, standard alphabet
  35. * - base64_dec(src, src_len, dst, dst_len) : decode from base64, standard alphabet
  36. * - base64_enc_len(len) : length needed to encode len bytes (macro)
  37. * - base64_max_dec_len(len) : maximum length needed to decode len bytes (macro)
  38. * - base64_dec_len(str, len) : size of the decoded str
  39. * - q_base64_enc(src, src_len, dst, dst_len) : encode to special base64 alphabet (non standard)
  40. * - q_base64_dec(src, src_len, dst, dst_len) - decode from special non-standard base64 alphabet
  41. *
  42. * All the above functions return the size used (in dst) on success and
  43. * 0 or a negative number (which is -1*size_needed) on error.
  44. *
  45. * There are close to no checks for validity, an unexpected char will lead
  46. * to a corrupted result, but the functions won't return error.
  47. *
  48. * Notes:
  49. * on a core2 duo the versions with lookup tables are way faster (see
  50. * http://www.experts-exchange.com/Programming/Languages/CPP/Q_21988706.html
  51. * for some interesting tests and ideeas).
  52. *
  53. * Test results for 40 bytes (typical ser nounce) in average cpu cycles:
  54. \verbatim
  55. * lookup lookup_large lookup8k no-lookup
  56. * base16_enc 211/231 218/199 - 1331
  57. * base16_dec 252/251 236 - 1226
  58. * base64_enc 209 186 156 1005
  59. * base64_dec 208 207 207 1242
  60. * q_base64_enc - 288
  61. * q_base64_dec - 281
  62. * (see test/basex.txt for more results)
  63. \endverbatim
  64. *
  65. * Defines:
  66. * - BASE64_LOOKUP_TABLE/NO_BASE64_LOOKUP_TABLE : use (default)/don't use
  67. * small lookup tables for conversions (faster in general).
  68. * - BASE64_LOOKUP_LARGE : use large lookup tables (2560 bytes for
  69. * encoding and 256 bytes for decoding; without it 64 bytes are used for
  70. * encoding and 85 bytes for decoding.
  71. * - BASE64_LOOKUP_8K : use even larger lookup tables (8K for encoding and
  72. * 256 for decoding); also try to write 2 bytes at a time (short) if
  73. * the destination is 2 byte aligned
  74. *
  75. * - BASE16_LOOKUP_TABLE/NO_BASE16_LOOKUP_TABLE : use (default)/don't use
  76. * small lookup tables for conversions (faster in general).
  77. * - BASE16_LOOKUP_LARGE : use large lookup tables (512 bytes for
  78. * encoding and 256 bytes for decoding
  79. * - BASE16_READ_WHOLE_INTS : read an int at a time
  80. *
  81. * History:
  82. * --------
  83. * 2008-06-11 created by andrei
  84. */
  85. #ifndef _basex_h
  86. #define _basex_h
  87. #include "compiler_opt.h"
  88. /* defaults */
  89. #ifndef NO_BASE16_LOOKUP_TABLE
  90. #define BASE16_LOOKUP_TABLE
  91. #endif
  92. #ifndef NO_BASE64_LOOKUP_TABLE
  93. #define BASE64_LOOKUP_TABLE
  94. #endif
  95. #ifndef NO_BASE64_LOOKUP_8K
  96. #define BASE64_LOOKUP_8K
  97. #endif
  98. #ifndef NO_BASE16_LOOKUP_LARGE
  99. #define BASE16_LOOKUP_LARGE
  100. #endif
  101. #if !defined NO_BASE64_LOOKUP_LARGE && !defined BASE64_LOOKUP_8K
  102. #define BASE64_LOOKUP_LARGE
  103. #endif
  104. #if defined BASE16_READ_WHOLE_INTS || defined BASE64_READ_WHOLE_INTS || \
  105. defined BASE64_LOOKUP_8K
  106. #include "endianness.h"
  107. /*! \brief aligns p to a type* pointer, type must have a 2^k size */
  108. #define ALIGN_POINTER(p, type) \
  109. ((type*) ((long)((char*)(p)+sizeof(type)-1)&~(long)(sizeof(type)-1)))
  110. #define ALIGN_UINT_POINTER(p) ALIGN_POINTER(p, unsigned int)
  111. #endif
  112. #ifdef BASE16_LOOKUP_TABLE
  113. #ifdef BASE16_LOOKUP_LARGE
  114. /*! \brief use large tables: 512 for lookup and 256 for decode */
  115. extern unsigned char _bx_hexdig_hi[256];
  116. extern unsigned char _bx_hexdig_low[256];
  117. /*! \brief returns the first 4 bits of c converted to a hex digit */
  118. #define HEX_HI(h) _bx_hexdig_hi[(unsigned char)(h)]
  119. /*! \brief returns the low 4 bits of converted to a hex digit */
  120. #define HEX_LOW(h) _bx_hexdig_low[(unsigned char)(h)]
  121. extern unsigned char _bx_unhexdig256[256];
  122. /*! \brief converts hex_digit to a number (0..15); it might
  123. * \return 0xff for invalid digit (but with some compile
  124. * option it won't check)
  125. */
  126. #define UNHEX(h) _bx_unhexdig256[(h)]
  127. #else /* BASE16_LOOKUP_LARGE */
  128. /*! \brief use small tabes: 16 bytes for lookup and 32 for decode */
  129. extern unsigned char _bx_hexdig[16+1];
  130. #define HEX_4BITS(h) _bx_hexdig[(h)]
  131. #define HEX_HI(h) HEX_4BITS(((unsigned char)(h))>>4)
  132. #define HEX_LOW(h) HEX_4BITS((h)&0xf)
  133. extern unsigned char _bx_unhexdig32[32];
  134. #define UNHEX(h) _bx_unhexdig32[(((h))-'0')&0x1f]
  135. #endif /* BASE16_LOOKUP_LARGE */
  136. #else /* BASE16_LOOKUP_TABLE */
  137. /* no lookup tables */
  138. #if 0
  139. #define HEX_4BITS(h) (unsigned char)((unlikely((h)>=10))?((h)-10+'A'):(h)+'0')
  140. #define UNHEX(c) (unsigned char)((unlikely((c)>='A'))?(c)-'A'+10:(c)-'0')
  141. #else
  142. #define HEX_4BITS(hc) (unsigned char)( ((((hc)>=10)-1)&((hc)+'0')) | \
  143. ((((hc)<10)-1)&((hc)+'A')) )
  144. #define UNHEX(c) (unsigned char) ( ((((c)>'9')-1)& ((c)-'0')) | \
  145. ((((c)<='9')-1)&((c)-'A')) )
  146. #endif
  147. #define HEX_HI(h) HEX_4BITS(((unsigned char)(h))>>4)
  148. #define HEX_LOW(h) HEX_4BITS((h)&0xf)
  149. #endif /* BASE16_LOOKUP_TABLE */
  150. #ifdef BASE64_LOOKUP_TABLE
  151. #ifdef BASE64_LOOKUP_LARGE
  152. /* large lookup tables, 2.5 k */
  153. extern unsigned char _bx_b64_first[256];
  154. extern unsigned char _bx_b64_second[4][256];
  155. extern unsigned char _bx_b64_third[4][256];
  156. extern unsigned char _bx_b64_fourth[256];
  157. #define BASE64_1(a) _bx_b64_first[(a)]
  158. #define BASE64_2(a,b) _bx_b64_second[(a)&0x3][(b)]
  159. #define BASE64_3(b,c) _bx_b64_third[(c)>>6][(b)]
  160. #define BASE64_4(c) _bx_b64_fourth[(c)]
  161. extern unsigned char _bx_ub64[256];
  162. #define UNBASE64(v) _bx_ub64[(v)]
  163. #elif defined BASE64_LOOKUP_8K
  164. /* even larger encode tables: 8k */
  165. extern unsigned short _bx_b64_12[4096];
  166. /* return a word (16 bits) */
  167. #define BASE64_12(a,b) _bx_b64_12[((a)<<4)|((b)>>4)]
  168. #define BASE64_34(b,c) _bx_b64_12[(((b)&0xf)<<8)|(c)]
  169. #ifdef __IS_LITTLE_ENDIAN
  170. #define FIRST_8B(s) ((unsigned char)(s))
  171. #define LAST_8B(s) ((s)>>8)
  172. #elif defined __IS_BIG_ENDIAN
  173. #define FIRST_8B(s) ((s)>>8)
  174. #define LAST_8B(s) ((unsigned char)(s))
  175. #else
  176. #error neither __IS_LITTLE_ENDIAN nor __IS_BIG_ENDIAN are defined
  177. #endif
  178. extern unsigned char _bx_ub64[256];
  179. #define UNBASE64(v) _bx_ub64[(v)]
  180. #else /* BASE64_LOOKUP_LARGE */
  181. /* small lookup tables */
  182. extern unsigned char _bx_b64[64+1];
  183. #define BASE64_DIG(v) _bx_b64[(v)]
  184. #define BASE64_1(a) BASE64_DIG((a)>>2)
  185. #define BASE64_2(a, b) BASE64_DIG( (((a)<<4)&0x3f) | ((b)>>4))
  186. #define BASE64_3(b, c) BASE64_DIG( (((b)<<2)&0x3f) | ((c)>>6))
  187. #define BASE64_4(c) BASE64_DIG((c)&0x3f)
  188. extern unsigned char _bx_ub64[0x54+1];
  189. #define UNBASE64(v) _bx_ub64[(((v)&0x7f)-0x2b)]
  190. #endif /* BASE64_LOOKUP_LARGE */
  191. #else /* BASE64_LOOKUP_TABLE */
  192. #define BASE64_DIG(v) base64_enc_char(v)
  193. #define BASE64_1(a) BASE64_DIG((a)>>2)
  194. #define BASE64_2(a, b) BASE64_DIG( (((a)<<4)&0x3f) | ((b)>>4))
  195. #define BASE64_3(b, c) BASE64_DIG( (((b)<<2)&0x3f) | ((c)>>6))
  196. #define BASE64_4(c) BASE64_DIG((c)&0x3f)
  197. #define UNBASE64(v) base64_dec_char(v)
  198. #endif /* BASE64_LOOKUP_TABLE */
  199. /*! \brief lenght needed for encoding l bytes */
  200. #define base16_enc_len(l) (l*2)
  201. /*! \brief maximum lenght needed for decoding l bytes */
  202. #define base16_max_dec_len(l) (l/2)
  203. /*! \brief actual space needed for decoding a string b of size l */
  204. #define base16_dec_len(b, l) base16_max_dec_len(l)
  205. /*! \brief minimum valid source len for decoding */
  206. #define base16_dec_min_len() 2
  207. /*! \brief minimum valid source len for encoding */
  208. #define base16_enc_min_len() 0
  209. /*! \brief space needed for encoding l bytes */
  210. #define base64_enc_len(l) (((l)+2)/3*4)
  211. /*! \brief maximum space needed for encoding l bytes */
  212. #define base64_max_dec_len(l) ((l)/4*3)
  213. /*! \brief actual space needed for decoding a string b of size l, l>=4 */
  214. #define base64_dec_len(b, l) \
  215. (base64_max_dec_len(l)-((b)[(l)-2]=='=') -((b)[(l)-1]=='='))
  216. /*! \brief minimum valid source len for decoding */
  217. #define base64_dec_min_len() 4
  218. /*! \brief minimum valid source len for encoding */
  219. #define base64_enc_min_len() 0
  220. #ifdef BASE16_READ_WHOLE_INTS
  221. /*!
  222. * \params:
  223. * \return: size used from the output buffer (dst) on success,
  224. * -size_needed on error
  225. *
  226. * WARNING: the output string is not 0-term
  227. */
  228. inline static int base16_enc(unsigned char* src, int slen, unsigned char* dst, int dlen)
  229. {
  230. unsigned int* p;
  231. unsigned char* end;
  232. int osize;
  233. unsigned short us;
  234. osize=2*slen;
  235. if (unlikely(dlen<osize))
  236. return -osize;
  237. end=src+slen;
  238. p=ALIGN_UINT_POINTER(src);
  239. if (likely((unsigned char*)p<end)){
  240. switch((unsigned char)((unsigned char*)p-src)){
  241. case 3:
  242. *dst=HEX_HI(*src);
  243. *(dst+1)=HEX_LOW(*src);
  244. dst+=2;
  245. src++;
  246. /* no break */
  247. case 2:
  248. us=*(unsigned short*)(src);
  249. #if defined __IS_LITTLE_ENDIAN
  250. *(dst+0)=HEX_HI(us);
  251. *(dst+1)=HEX_LOW(us);
  252. *(dst+2)=HEX_HI(us>>8);
  253. *(dst+3)=HEX_LOW(us>>8);
  254. #elif defined __IS_BIG_ENDIAN
  255. *(dst+2)=HEX_HI(us);
  256. *(dst+3)=HEX_LOW(us);
  257. *(dst+0)=HEX_HI(us>>8);
  258. *(dst+1)=HEX_LOW(us>>8);
  259. #endif
  260. dst+=4;
  261. /* no need to inc src */
  262. break;
  263. case 1:
  264. *dst=HEX_HI(*src);
  265. *(dst+1)=HEX_LOW(*src);
  266. dst+=2;
  267. /* no need to inc src */
  268. case 0:
  269. break;
  270. }
  271. for(;(unsigned char*)p<=(end-4);p++,dst+=8){
  272. #if defined __IS_LITTLE_ENDIAN
  273. *(dst+0)=HEX_HI(*p);
  274. *(dst+1)=HEX_LOW(*p);
  275. *(dst+2)=HEX_HI(((*p)>>8));
  276. *(dst+3)=HEX_LOW(((*p)>>8));
  277. *(dst+4)=HEX_HI(((*p)>>16));
  278. *(dst+5)=HEX_LOW(((*p)>>16));
  279. *(dst+6)=HEX_HI(((*p)>>24));
  280. *(dst+7)=HEX_LOW(((*p)>>24));
  281. #elif defined __IS_BIG_ENDIAN
  282. *(dst+6)=HEX_HI(*p);
  283. *(dst+7)=HEX_LOW(*p);
  284. *(dst+4)=HEX_HI(((*p)>>8));
  285. *(dst+5)=HEX_LOW(((*p)>>8));
  286. *(dst+2)=HEX_HI(((*p)>>16));
  287. *(dst+3)=HEX_LOW(((*p)>>16));
  288. *(dst+0)=HEX_HI(((*p)>>24));
  289. *(dst+1)=HEX_LOW(((*p)>>24));
  290. #else
  291. #error neither BIG ro LITTLE endian defined
  292. #endif /* __IS_*_ENDIAN */
  293. }
  294. src=(unsigned char*)p;
  295. /* src is 2-bytes aligned (short) */
  296. switch((unsigned char)((unsigned char*)end-src)){
  297. case 3:
  298. case 2:
  299. us=*(unsigned short*)(src);
  300. #if defined __IS_LITTLE_ENDIAN
  301. *(dst+0)=HEX_HI(us);
  302. *(dst+1)=HEX_LOW(us);
  303. *(dst+2)=HEX_HI(us>>8);
  304. *(dst+3)=HEX_LOW(us>>8);
  305. #elif defined __IS_BIG_ENDIAN
  306. *(dst+2)=HEX_HI(us);
  307. *(dst+3)=HEX_LOW(us);
  308. *(dst+0)=HEX_HI(us>>8);
  309. *(dst+1)=HEX_LOW(us>>8);
  310. #endif
  311. if ((end-src)==3){
  312. *(dst+4)=HEX_HI(*(src+2));
  313. *(dst+5)=HEX_LOW(*(src+2));
  314. }
  315. /* no need to inc anything */
  316. break;
  317. case 1:
  318. *dst=HEX_HI(*src);
  319. *(dst+1)=HEX_LOW(*src);
  320. /* no need to inc anything */
  321. case 0:
  322. break;
  323. }
  324. }else if (unlikely((long)src&1)){
  325. /* src is not 2-bytes (short) aligned */
  326. switch((unsigned char)((unsigned char*)end-src)){
  327. case 3:
  328. *dst=HEX_HI(*src);
  329. *(dst+1)=HEX_LOW(*src);
  330. dst+=2;
  331. src++;
  332. /* no break */
  333. case 2:
  334. us=*(unsigned short*)(src);
  335. #if defined __IS_LITTLE_ENDIAN
  336. *(dst+0)=HEX_HI(us);
  337. *(dst+1)=HEX_LOW(us);
  338. *(dst+2)=HEX_HI(us>>8);
  339. *(dst+3)=HEX_LOW(us>>8);
  340. #elif defined __IS_BIG_ENDIAN
  341. *(dst+2)=HEX_HI(us);
  342. *(dst+3)=HEX_LOW(us);
  343. *(dst+0)=HEX_HI(us>>8);
  344. *(dst+1)=HEX_LOW(us>>8);
  345. #endif
  346. /* no need to inc anything */
  347. break;
  348. case 1:
  349. *dst=HEX_HI(*src);
  350. *(dst+1)=HEX_LOW(*src);
  351. /* no need to inc anything */
  352. case 0:
  353. break;
  354. }
  355. }else{
  356. /* src is 2-bytes aligned (short) */
  357. switch((unsigned char)((unsigned char*)end-src)){
  358. case 3:
  359. case 2:
  360. us=*(unsigned short*)(src);
  361. #if defined __IS_LITTLE_ENDIAN
  362. *(dst+0)=HEX_HI(us);
  363. *(dst+1)=HEX_LOW(us);
  364. *(dst+2)=HEX_HI(us>>8);
  365. *(dst+3)=HEX_LOW(us>>8);
  366. #elif defined __IS_BIG_ENDIAN
  367. *(dst+2)=HEX_HI(us);
  368. *(dst+3)=HEX_LOW(us);
  369. *(dst+0)=HEX_HI(us>>8);
  370. *(dst+1)=HEX_LOW(us>>8);
  371. #endif
  372. if ((end-src)==3){
  373. *(dst+4)=HEX_HI(*(src+2));
  374. *(dst+5)=HEX_LOW(*(src+2));
  375. }
  376. /* no need to inc anything */
  377. break;
  378. case 1:
  379. *dst=HEX_HI(*src);
  380. *(dst+1)=HEX_LOW(*src);
  381. /* no need to inc anything */
  382. case 0:
  383. break;
  384. }
  385. }
  386. return osize;
  387. }
  388. #else /* BASE16_READ_WHOLE_INTS */
  389. /*!
  390. * \return : size used from the output buffer (dst) on success,
  391. * -size_needed on error
  392. *
  393. * \note WARNING: the output string is not 0-term
  394. */
  395. inline static int base16_enc(unsigned char* src, int slen,
  396. unsigned char* dst, int dlen)
  397. {
  398. unsigned char* end;
  399. int osize;
  400. osize=2*slen;
  401. if (unlikely(dlen<osize))
  402. return -osize;
  403. end=src+slen;
  404. for (;src<end; src++,dst+=2){
  405. *dst=HEX_HI(*src);
  406. *(dst+1)=HEX_LOW(*src);
  407. }
  408. return osize;
  409. }
  410. #endif /* BASE16_READ_WHOLE_INTS */
  411. inline static int base16_dec(unsigned char* src, int slen, unsigned char* dst, int dlen)
  412. {
  413. unsigned char* end;
  414. int osize;
  415. osize=slen/2;
  416. if (unlikely(dlen<osize))
  417. return -osize;
  418. end=src+2*osize;
  419. for (; src<end; src+=2, dst++)
  420. *dst=(UNHEX(*src)<<4) | UNHEX(*(src+1));
  421. return osize;
  422. }
  423. /*! \brief helper internal function: encodes v (6 bits value)
  424. * \return char ascii encoding on success and 0xff on error
  425. * (value out of range) */
  426. inline static unsigned char base64_enc_char(unsigned char v)
  427. {
  428. switch(v){
  429. case 0x3f:
  430. return '/';
  431. case 0x3e:
  432. return '+';
  433. default:
  434. if (v<=25)
  435. return v+'A';
  436. else if (v<=51)
  437. return v-26+'a';
  438. else if (v<=61)
  439. return v-52+'0';
  440. }
  441. return 0xff;
  442. }
  443. /*! \brief helper internal function: decodes a base64 "digit",
  444. * \return value on success (0-63) and 0xff on error (invalid)*/
  445. inline static unsigned base64_dec_char(unsigned char v)
  446. {
  447. switch(v){
  448. case '/':
  449. return 0x3f;
  450. case '+':
  451. return 0x3e;
  452. case ':':
  453. case ';':
  454. case '<':
  455. case '=':
  456. case '>':
  457. case '?':
  458. case '@':
  459. case '[':
  460. case '\\':
  461. case ']':
  462. case '^':
  463. case '_':
  464. case '`':
  465. return 0xff;
  466. default:
  467. if ((v)<'0')
  468. return 0xff;
  469. if ((v)<='9')
  470. return (v)-'0'+0x34;
  471. else if ((v)<='Z')
  472. return (v)-'A';
  473. else if ((v) <='z')
  474. return (v)-'a'+0x1a;
  475. }
  476. return 0xff;
  477. }
  478. #ifdef BASE64_LOOKUP_8K
  479. /*!
  480. * \return : size used from the output buffer (dst) on success ((slen+2)/3*4)
  481. * -size_needed on error
  482. *
  483. * \note WARNING: the output string is not 0-term
  484. */
  485. inline static int base64_enc(unsigned char* src, int slen,
  486. unsigned char* dst, int dlen)
  487. {
  488. unsigned char* end;
  489. int osize;
  490. osize=(slen+2)/3*4;
  491. if (unlikely(dlen<osize))
  492. return -osize;
  493. end=src+slen/3*3;
  494. if (unlikely((long)dst%2)){
  495. for (;src<end; src+=3,dst+=4){
  496. dst[0]=FIRST_8B(BASE64_12(src[0], src[1]));
  497. dst[1]=LAST_8B(BASE64_12(src[0], src[1]));
  498. dst[2]=FIRST_8B(BASE64_34(src[1], src[2]));
  499. dst[3]=LAST_8B(BASE64_34(src[1], src[2]));
  500. }
  501. switch(slen%3){
  502. case 2:
  503. dst[0]=FIRST_8B(BASE64_12(src[0], src[1]));
  504. dst[1]=LAST_8B(BASE64_12(src[0], src[1]));
  505. dst[2]=FIRST_8B(BASE64_34(src[1], 0));
  506. dst[3]='=';
  507. break;
  508. case 1:
  509. dst[0]=FIRST_8B(BASE64_12(src[0], 0));
  510. dst[1]=LAST_8B(BASE64_12(src[0], 0));
  511. dst[2]='=';
  512. dst[3]='=';
  513. break;
  514. }
  515. }else{
  516. for (;src<end; src+=3,dst+=4){
  517. *(unsigned short*)(dst+0)=_bx_b64_12[(src[0]<<4)|(src[1]>>4)];
  518. *(unsigned short*)(dst+2)=_bx_b64_12[((src[1]&0xf)<<8)|src[2]];
  519. }
  520. switch(slen%3){
  521. case 2:
  522. *(unsigned short*)(dst+0)=_bx_b64_12[(src[0]<<4)|(src[1]>>4)];
  523. *(unsigned short*)(dst+2)=_bx_b64_12[((src[1]&0xf)<<8)|0];
  524. dst[3]='=';
  525. break;
  526. case 1:
  527. *(unsigned short*)(dst+0)=_bx_b64_12[(src[0]<<4)|0];
  528. dst[2]='=';
  529. dst[3]='=';
  530. break;
  531. }
  532. }
  533. return osize;
  534. }
  535. #else /*BASE64_LOOKUP_8K*/
  536. /*! \brief Convert to base64
  537. * \return size used from the output buffer (dst) on success ((slen+2)/3*4)
  538. * -size_needed on error
  539. * \note WARNING: the output string is not 0-term
  540. */
  541. inline static int base64_enc(unsigned char* src, int slen,
  542. unsigned char* dst, int dlen)
  543. {
  544. unsigned char* end;
  545. int osize;
  546. osize=(slen+2)/3*4;
  547. if (unlikely(dlen<osize))
  548. return -osize;
  549. end=src+slen/3*3;
  550. for (;src<end; src+=3,dst+=4){
  551. dst[0]=BASE64_1(src[0]);
  552. dst[1]=BASE64_2(src[0], src[1]);
  553. dst[2]=BASE64_3(src[1], src[2]);
  554. dst[3]=BASE64_4(src[2]);
  555. }
  556. switch(slen%3){
  557. case 2:
  558. dst[0]=BASE64_1(src[0]);
  559. dst[1]=BASE64_2(src[0], src[1]);
  560. dst[2]=BASE64_3(src[1], 0);
  561. dst[3]='=';
  562. break;
  563. case 1:
  564. dst[0]=BASE64_1(src[0]);
  565. dst[1]=BASE64_2(src[0], 0);
  566. dst[2]='=';
  567. dst[3]='=';
  568. break;
  569. }
  570. return osize;
  571. }
  572. #endif /*BASE64_LOOKUP_8K*/
  573. /*! \brief
  574. * \return size used from the output buffer (dst) on success (max: slen/4*3)
  575. * -size_needed on error or 0 on bad base64 encoded string
  576. * \note WARNING: the output string is not 0-term
  577. */
  578. inline static int base64_dec(unsigned char* src, int slen,
  579. unsigned char* dst, int dlen)
  580. {
  581. unsigned char* end;
  582. int osize;
  583. register unsigned a, b, c, d; /* more registers used, but allows for
  584. paralles execution */
  585. if (unlikely((slen<4) || (slen%4) ||
  586. (src[slen-2]=='=' && src[slen-1]!='=')))
  587. return 0; /* invalid base64 enc. */
  588. osize=(slen/4*3)-(src[slen-2]=='=')-(src[slen-1]=='=');
  589. if (unlikely(dlen<osize))
  590. return -osize;
  591. end=src+slen-4;
  592. for (;src<end; src+=4,dst+=3){
  593. #if 0
  594. u= (UNBASE64(src[0])<<18) | (UNBASE64(src[1])<<12) |
  595. (UNBASE64(src[2])<<6) | UNBASE64(src[3]);
  596. dst[0]=u>>16;
  597. dst[1]=u>>8;
  598. dst[3]=u;
  599. #endif
  600. a=UNBASE64(src[0]);
  601. b=UNBASE64(src[1]);
  602. c=UNBASE64(src[2]);
  603. d=UNBASE64(src[3]);
  604. dst[0]=(a<<2) | (b>>4);
  605. dst[1]=(b<<4) | (c>>2);
  606. dst[2]=(c<<6) | d;
  607. }
  608. switch(osize%3){
  609. case 0: /* no '=' => 3 output bytes at the end */
  610. a=UNBASE64(src[0]);
  611. b=UNBASE64(src[1]);
  612. c=UNBASE64(src[2]);
  613. d=UNBASE64(src[3]);
  614. dst[0]=(a<<2) | (b>>4);
  615. dst[1]=(b<<4) | (c>>2);
  616. dst[2]=(c<<6) | d;
  617. break;
  618. case 2: /* 1 '=' => 2 output bytes at the end */
  619. a=UNBASE64(src[0]);
  620. b=UNBASE64(src[1]);
  621. c=UNBASE64(src[2]);
  622. dst[0]=(a<<2) | (b>>4);
  623. dst[1]=(b<<4) | (c>>2);
  624. break;
  625. case 1: /* 2 '=' => 1 output byte at the end */
  626. a=UNBASE64(src[0]);
  627. b=UNBASE64(src[1]);
  628. dst[0]=(a<<2) | (b>>4);
  629. break;
  630. }
  631. return osize;
  632. }
  633. /*! \brief
  634. * same as \ref base64_enc() but with a different alphabet, that allows simpler and
  635. * faster enc/dec
  636. * \return size used from the output buffer (dst) on success ((slen+2)/3*4)
  637. * -size_needed on error
  638. * \note WARNING: the alphabet includes ":;<>?@[]\`", so it might not be suited
  639. * in all cases (e.g. encoding something in a sip uri).
  640. */
  641. inline static int q_base64_enc(unsigned char* src, int slen,
  642. unsigned char* dst, int dlen)
  643. {
  644. #define q_b64_base '0'
  645. #define q_b64_pad 'z'
  646. #define Q_BASE64(v) (unsigned char)((v)+q_b64_base)
  647. unsigned char* end;
  648. int osize;
  649. osize=(slen+2)/3*4;
  650. if (unlikely(dlen<osize))
  651. return -osize;
  652. end=src+slen/3*3;
  653. for (;src<end; src+=3,dst+=4){
  654. dst[0]=Q_BASE64(src[0]>>2);
  655. dst[1]=(Q_BASE64((src[0]<<4)&0x3f) | (src[1]>>4));
  656. dst[2]=(Q_BASE64((src[1]<<2)&0x3f) | (src[2]>>6) );
  657. dst[3]=Q_BASE64(src[2]&0x3f);
  658. }
  659. switch(slen%3){
  660. case 2:
  661. dst[0]=Q_BASE64(src[0]>>2);
  662. dst[1]=(Q_BASE64((src[0]<<4)&0x3f) | (src[1]>>4));
  663. dst[2]=Q_BASE64((src[1]<<2)&0x3f);
  664. dst[3]=q_b64_pad;
  665. break;
  666. case 1:
  667. dst[0]=Q_BASE64(src[0]>>2);
  668. dst[1]=Q_BASE64((src[0]<<4)&0x3f);
  669. dst[2]=q_b64_pad;
  670. dst[3]=q_b64_pad;
  671. break;
  672. }
  673. return osize;
  674. #undef Q_BASE64
  675. }
  676. /*! \brief
  677. * same as \ref base64_enc() but with a different alphabet, that allows simpler and
  678. * faster enc/dec
  679. *
  680. * \return size used from the output buffer (dst) on success (max: slen/4*3)
  681. * -size_needed on error or 0 on bad base64 encoded string
  682. * \note WARNING: the output string is not 0-term
  683. */
  684. inline static int q_base64_dec(unsigned char* src, int slen,
  685. unsigned char* dst, int dlen)
  686. {
  687. #define Q_UNBASE64(v) (unsigned char)((v)-q_b64_base)
  688. unsigned char* end;
  689. int osize;
  690. #ifdef SINGLE_REG
  691. register unsigned u;
  692. #else
  693. register unsigned a, b, c, d; /* more registers used, but allows for
  694. paralles execution */
  695. #endif
  696. if (unlikely((slen<4) || (slen%4) ||
  697. (src[slen-2]==q_b64_pad && src[slen-1]!=q_b64_pad)))
  698. return 0; /* invalid base64 enc. */
  699. osize=(slen/4*3)-(src[slen-2]==q_b64_pad)-(src[slen-1]==q_b64_pad);
  700. if (unlikely(dlen<osize))
  701. return -osize;
  702. end=src+slen-4;
  703. for (;src<end; src+=4,dst+=3){
  704. #ifdef SINGLE_REG
  705. u= (Q_UNBASE64(src[0])<<18) | (Q_UNBASE64(src[1])<<12) |
  706. (Q_UNBASE64(src[2])<<6) | Q_UNBASE64(src[3]);
  707. dst[0]=u>>16;
  708. dst[1]=u>>8;
  709. dst[2]=u;
  710. #else
  711. a=Q_UNBASE64(src[0]);
  712. b=Q_UNBASE64(src[1]);
  713. c=Q_UNBASE64(src[2]);
  714. d=Q_UNBASE64(src[3]);
  715. dst[0]=(a<<2) | (b>>4);
  716. dst[1]=(b<<4) | (c>>2);
  717. dst[2]=(c<<6) | d;
  718. #endif
  719. }
  720. switch(osize%3){
  721. case 0: /* no '=' => 3 output bytes at the end */
  722. #ifdef SINGLE_REG
  723. u= (Q_UNBASE64(src[0])<<18) | (Q_UNBASE64(src[1])<<12) |
  724. (Q_UNBASE64(src[2])<<6) | Q_UNBASE64(src[3]);
  725. dst[0]=u>>16;
  726. dst[1]=u>>8;
  727. dst[2]=u;
  728. #else
  729. a=Q_UNBASE64(src[0]);
  730. b=Q_UNBASE64(src[1]);
  731. c=Q_UNBASE64(src[2]);
  732. d=Q_UNBASE64(src[3]);
  733. dst[0]=(a<<2) | (b>>4);
  734. dst[1]=(b<<4) | (c>>2);
  735. dst[2]=(c<<6) | d;
  736. #endif
  737. break;
  738. case 2: /* 1 '=' => 2 output bytes at the end */
  739. #ifdef SINGLE_REG
  740. u= (Q_UNBASE64(src[0])<<12) | (Q_UNBASE64(src[1])<<6) |
  741. (Q_UNBASE64(src[2]));
  742. dst[0]=u>>10;
  743. dst[1]=u>>2;
  744. #else
  745. a=Q_UNBASE64(src[0]);
  746. b=Q_UNBASE64(src[1]);
  747. c=Q_UNBASE64(src[2]);
  748. dst[0]=(a<<2) | (b>>4);
  749. dst[1]=(b<<4) | (c>>2);
  750. #endif
  751. break;
  752. case 1: /* 2 '=' => 1 output byte at the end */
  753. #ifdef SINGLE_REG
  754. dst[0]=(Q_UNBASE64(src[0])<<2) | (Q_UNBASE64(src[1])>>4);
  755. #else
  756. a=Q_UNBASE64(src[0]);
  757. b=Q_UNBASE64(src[1]);
  758. dst[0]=(a<<2) | (b>>4);
  759. #endif
  760. break;
  761. }
  762. return osize;
  763. #undef q_b64_base
  764. #undef q_b64_pad
  765. }
  766. /*! \brief inits internal lookup tables */
  767. int init_basex(void);
  768. #endif /* _basex_h */