HexEncoder.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
  2. using System;
  3. using System.IO;
  4. namespace Org.BouncyCastle.Utilities.Encoders
  5. {
  6. public class HexEncoder
  7. : IEncoder
  8. {
  9. protected readonly byte[] encodingTable =
  10. {
  11. (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7',
  12. (byte)'8', (byte)'9', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f'
  13. };
  14. /*
  15. * set up the decoding table.
  16. */
  17. protected readonly byte[] decodingTable = new byte[128];
  18. protected void InitialiseDecodingTable()
  19. {
  20. Arrays.Fill(decodingTable, (byte)0xff);
  21. for (int i = 0; i < encodingTable.Length; i++)
  22. {
  23. decodingTable[encodingTable[i]] = (byte)i;
  24. }
  25. decodingTable['A'] = decodingTable['a'];
  26. decodingTable['B'] = decodingTable['b'];
  27. decodingTable['C'] = decodingTable['c'];
  28. decodingTable['D'] = decodingTable['d'];
  29. decodingTable['E'] = decodingTable['e'];
  30. decodingTable['F'] = decodingTable['f'];
  31. }
  32. public HexEncoder()
  33. {
  34. InitialiseDecodingTable();
  35. }
  36. /**
  37. * encode the input data producing a Hex output stream.
  38. *
  39. * @return the number of bytes produced.
  40. */
  41. public int Encode(
  42. byte[] data,
  43. int off,
  44. int length,
  45. Stream outStream)
  46. {
  47. for (int i = off; i < (off + length); i++)
  48. {
  49. int v = data[i];
  50. outStream.WriteByte(encodingTable[v >> 4]);
  51. outStream.WriteByte(encodingTable[v & 0xf]);
  52. }
  53. return length * 2;
  54. }
  55. private static bool Ignore(char c)
  56. {
  57. return c == '\n' || c =='\r' || c == '\t' || c == ' ';
  58. }
  59. /**
  60. * decode the Hex encoded byte data writing it to the given output stream,
  61. * whitespace characters will be ignored.
  62. *
  63. * @return the number of bytes produced.
  64. */
  65. public int Decode(
  66. byte[] data,
  67. int off,
  68. int length,
  69. Stream outStream)
  70. {
  71. byte b1, b2;
  72. int outLen = 0;
  73. int end = off + length;
  74. while (end > off)
  75. {
  76. if (!Ignore((char)data[end - 1]))
  77. {
  78. break;
  79. }
  80. end--;
  81. }
  82. int i = off;
  83. while (i < end)
  84. {
  85. while (i < end && Ignore((char)data[i]))
  86. {
  87. i++;
  88. }
  89. b1 = decodingTable[data[i++]];
  90. while (i < end && Ignore((char)data[i]))
  91. {
  92. i++;
  93. }
  94. b2 = decodingTable[data[i++]];
  95. if ((b1 | b2) >= 0x80)
  96. throw new IOException("invalid characters encountered in Hex data");
  97. outStream.WriteByte((byte)((b1 << 4) | b2));
  98. outLen++;
  99. }
  100. return outLen;
  101. }
  102. /**
  103. * decode the Hex encoded string data writing it to the given output stream,
  104. * whitespace characters will be ignored.
  105. *
  106. * @return the number of bytes produced.
  107. */
  108. public int DecodeString(
  109. string data,
  110. Stream outStream)
  111. {
  112. byte b1, b2;
  113. int length = 0;
  114. int end = data.Length;
  115. while (end > 0)
  116. {
  117. if (!Ignore(data[end - 1]))
  118. {
  119. break;
  120. }
  121. end--;
  122. }
  123. int i = 0;
  124. while (i < end)
  125. {
  126. while (i < end && Ignore(data[i]))
  127. {
  128. i++;
  129. }
  130. b1 = decodingTable[data[i++]];
  131. while (i < end && Ignore(data[i]))
  132. {
  133. i++;
  134. }
  135. b2 = decodingTable[data[i++]];
  136. if ((b1 | b2) >= 0x80)
  137. throw new IOException("invalid characters encountered in Hex data");
  138. outStream.WriteByte((byte)((b1 << 4) | b2));
  139. length++;
  140. }
  141. return length;
  142. }
  143. }
  144. }
  145. #endif