u64.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <u.h>
  2. #include <libc.h>
  3. enum {
  4. INVAL= 255
  5. };
  6. static uchar t64d[256] = {
  7. INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
  8. INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
  9. INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL, 62,INVAL,INVAL,INVAL, 63,
  10. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
  11. INVAL, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
  12. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,INVAL,INVAL,INVAL,INVAL,INVAL,
  13. INVAL, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
  14. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,INVAL,INVAL,INVAL,INVAL,INVAL,
  15. INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
  16. INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
  17. INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
  18. INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
  19. INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
  20. INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
  21. INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,
  22. INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL,INVAL
  23. };
  24. static char t64e[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  25. int
  26. dec64(uchar *out, int lim, char *in, int n)
  27. {
  28. ulong b24;
  29. uchar *start = out;
  30. uchar *e = out + lim;
  31. int i, c;
  32. b24 = 0;
  33. i = 0;
  34. while(n-- > 0){
  35. c = t64d[*(uchar*)in++];
  36. if(c == INVAL)
  37. continue;
  38. switch(i){
  39. case 0:
  40. b24 = c<<18;
  41. break;
  42. case 1:
  43. b24 |= c<<12;
  44. break;
  45. case 2:
  46. b24 |= c<<6;
  47. break;
  48. case 3:
  49. if(out + 3 > e)
  50. goto exhausted;
  51. b24 |= c;
  52. *out++ = b24>>16;
  53. *out++ = b24>>8;
  54. *out++ = b24;
  55. i = -1;
  56. break;
  57. }
  58. i++;
  59. }
  60. switch(i){
  61. case 2:
  62. if(out + 1 > e)
  63. goto exhausted;
  64. *out++ = b24>>16;
  65. break;
  66. case 3:
  67. if(out + 2 > e)
  68. goto exhausted;
  69. *out++ = b24>>16;
  70. *out++ = b24>>8;
  71. break;
  72. }
  73. exhausted:
  74. return out - start;
  75. }
  76. int
  77. enc64(char *out, int lim, uchar *in, int n)
  78. {
  79. int i;
  80. ulong b24;
  81. char *start = out;
  82. char *e = out + lim;
  83. for(i = n/3; i > 0; i--){
  84. b24 = (*in++)<<16;
  85. b24 |= (*in++)<<8;
  86. b24 |= *in++;
  87. if(out + 4 >= e)
  88. goto exhausted;
  89. *out++ = t64e[(b24>>18)];
  90. *out++ = t64e[(b24>>12)&0x3f];
  91. *out++ = t64e[(b24>>6)&0x3f];
  92. *out++ = t64e[(b24)&0x3f];
  93. }
  94. switch(n%3){
  95. case 2:
  96. b24 = (*in++)<<16;
  97. b24 |= (*in)<<8;
  98. if(out + 4 >= e)
  99. goto exhausted;
  100. *out++ = t64e[(b24>>18)];
  101. *out++ = t64e[(b24>>12)&0x3f];
  102. *out++ = t64e[(b24>>6)&0x3f];
  103. *out++ = '=';
  104. break;
  105. case 1:
  106. b24 = (*in)<<16;
  107. if(out + 4 >= e)
  108. goto exhausted;
  109. *out++ = t64e[(b24>>18)];
  110. *out++ = t64e[(b24>>12)&0x3f];
  111. *out++ = '=';
  112. *out++ = '=';
  113. break;
  114. }
  115. exhausted:
  116. *out = 0;
  117. return out - start;
  118. }