u64.c 3.2 KB

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