THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
2.8KB

  1. #include "cache.h"
  2. #undef DEBUG_85
  3. #ifdef DEBUG_85
  4. #define say(a) fprintf(stderr, a)
  5. #define say1(a,b) fprintf(stderr, a, b)
  6. #define say2(a,b,c) fprintf(stderr, a, b, c)
  7. #else
  8. #define say(a) do { /* nothing */ } while (0)
  9. #define say1(a,b) do { /* nothing */ } while (0)
  10. #define say2(a,b,c) do { /* nothing */ } while (0)
  11. #endif
  12. static const char en85[] = {
  13. '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  14. 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
  15. 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
  16. 'U', 'V', 'W', 'X', 'Y', 'Z',
  17. 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
  18. 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
  19. 'u', 'v', 'w', 'x', 'y', 'z',
  20. '!', '#', '$', '%', '&', '(', ')', '*', '+', '-',
  21. ';', '<', '=', '>', '?', '@', '^', '_', '`', '{',
  22. '|', '}', '~'
  23. };
  24. static char de85[256];
  25. static void prep_base85(void)
  26. {
  27. int i;
  28. if (de85['Z'])
  29. return;
  30. for (i = 0; i < ARRAY_SIZE(en85); i++) {
  31. int ch = en85[i];
  32. de85[ch] = i + 1;
  33. }
  34. }
  35. int decode_85(char *dst, const char *buffer, int len)
  36. {
  37. prep_base85();
  38. say2("decode 85 <%.*s>", len / 4 * 5, buffer);
  39. while (len) {
  40. unsigned acc = 0;
  41. int de, cnt = 4;
  42. unsigned char ch;
  43. do {
  44. ch = *buffer++;
  45. de = de85[ch];
  46. if (--de < 0)
  47. return error("invalid base85 alphabet %c", ch);
  48. acc = acc * 85 + de;
  49. } while (--cnt);
  50. ch = *buffer++;
  51. de = de85[ch];
  52. if (--de < 0)
  53. return error("invalid base85 alphabet %c", ch);
  54. /* Detect overflow. */
  55. if (0xffffffff / 85 < acc ||
  56. 0xffffffff - de < (acc *= 85))
  57. return error("invalid base85 sequence %.5s", buffer-5);
  58. acc += de;
  59. say1(" %08x", acc);
  60. cnt = (len < 4) ? len : 4;
  61. len -= cnt;
  62. do {
  63. acc = (acc << 8) | (acc >> 24);
  64. *dst++ = acc;
  65. } while (--cnt);
  66. }
  67. say("\n");
  68. return 0;
  69. }
  70. void encode_85(char *buf, const unsigned char *data, int bytes)
  71. {
  72. say("encode 85");
  73. while (bytes) {
  74. unsigned acc = 0;
  75. int cnt;
  76. for (cnt = 24; cnt >= 0; cnt -= 8) {
  77. unsigned ch = *data++;
  78. acc |= ch << cnt;
  79. if (--bytes == 0)
  80. break;
  81. }
  82. say1(" %08x", acc);
  83. for (cnt = 4; cnt >= 0; cnt--) {
  84. int val = acc % 85;
  85. acc /= 85;
  86. buf[cnt] = en85[val];
  87. }
  88. buf += 5;
  89. }
  90. say("\n");
  91. *buf = 0;
  92. }
  93. #ifdef DEBUG_85
  94. int main(int ac, char **av)
  95. {
  96. char buf[1024];
  97. if (!strcmp(av[1], "-e")) {
  98. int len = strlen(av[2]);
  99. encode_85(buf, av[2], len);
  100. if (len <= 26) len = len + 'A' - 1;
  101. else len = len + 'a' - 26 - 1;
  102. printf("encoded: %c%s\n", len, buf);
  103. return 0;
  104. }
  105. if (!strcmp(av[1], "-d")) {
  106. int len = *av[2];
  107. if ('A' <= len && len <= 'Z') len = len - 'A' + 1;
  108. else len = len - 'a' + 26 + 1;
  109. decode_85(buf, av[2]+1, len);
  110. printf("decoded: %.*s\n", len, buf);
  111. return 0;
  112. }
  113. if (!strcmp(av[1], "-t")) {
  114. char t[4] = { -1,-1,-1,-1 };
  115. encode_85(buf, t, 4);
  116. printf("encoded: D%s\n", buf);
  117. return 0;
  118. }
  119. }
  120. #endif