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.

245 lines
8.3 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text;
  5. namespace Apewer.Internals
  6. {
  7. internal class ByteHelper
  8. {
  9. /// <summary>所有字节取反。</summary>
  10. public static byte[] Adverse(byte[] argOrigin)
  11. {
  12. if (argOrigin == null) return Constant.EmptyBytes;
  13. if (argOrigin.Length < 1) return Constant.EmptyBytes;
  14. byte[] vba = new byte[argOrigin.Length];
  15. for (int i = 0; i < argOrigin.Length; i++) vba[i] = (byte)(255 - argOrigin[i]);
  16. return vba;
  17. }
  18. /// <summary>克隆字节数组。当源为 NULL 时,将获取零元素字节数组。</summary>
  19. public static byte[] Clone(byte[] argOrigin)
  20. {
  21. if (argOrigin == null) return Constant.EmptyBytes;
  22. if (argOrigin.LongLength < 0L) return Constant.EmptyBytes;
  23. var result = new byte[argOrigin.LongLength];
  24. argOrigin.CopyTo(result, 0L);
  25. return result;
  26. }
  27. /// <summary>为文本数据添加 BOM 字节,若已存在则忽略。</summary>
  28. public static byte[] AddTextBom(byte[] argOrigin)
  29. {
  30. if (argOrigin == null) return Constant.Bom;
  31. if (argOrigin.LongLength < 1L) return Constant.Bom;
  32. var memory = new MemoryStream();
  33. var length = argOrigin.Length;
  34. if (length > 2)
  35. {
  36. if ((argOrigin[0] != 0xEF) || (argOrigin[1] != 0xBB) || (argOrigin[2] != 0xBF))
  37. {
  38. memory.Write(Constant.Bom, 0, 3);
  39. }
  40. }
  41. if (length > 0)
  42. {
  43. memory.Write(argOrigin, 0, length);
  44. }
  45. var data = memory.ToArray();
  46. memory.Dispose();
  47. return data;
  48. }
  49. /// <summary>去除文本数据的 BOM 字节,若不存在则忽略。</summary>
  50. public static byte[] WipeTextBom(byte[] bytes)
  51. {
  52. if (bytes == null) return Constant.EmptyBytes;
  53. var length = bytes.Length;
  54. if (length >= 3)
  55. {
  56. if ((bytes[0] == 0xEF) && (bytes[1] == 0xBB) && (bytes[2] == 0xBF))
  57. {
  58. var memory = new MemoryStream();
  59. memory.Write(bytes, 3, length - 3);
  60. var result = memory.ToArray();
  61. memory.Dispose();
  62. return result;
  63. }
  64. }
  65. return bytes;
  66. }
  67. /// <summary>解析封装的数据,获取多个字节数组。</summary>
  68. public static List<byte[]> ToList(byte[] argBytes)
  69. {
  70. var list = new List<byte[]>();
  71. if (argBytes == null) return list;
  72. var ms = new MemoryStream(argBytes);
  73. int done = 0; // 已处理字节数。
  74. int count = 0; // 数组数量。
  75. int total = argBytes.Length; // 总字节数。
  76. byte[] a = new byte[4]; // 长度。
  77. byte[] b; // 数据。
  78. int l; // 长度。
  79. if (total >= 4)
  80. {
  81. ms.Read(a, 0, 4); done += 4;
  82. if (argBytes[0] <= 127)
  83. {
  84. count = GetInt32(a);
  85. for (int i = 0; i < count; i++)
  86. {
  87. bool addempty = true;
  88. if (done + 4 <= total)
  89. {
  90. ms.Read(a, 0, 4); done += 4;
  91. l = GetInt32(a);
  92. if (l > 0)
  93. {
  94. if (done + l > total) l = total - done;
  95. if (l > 0)
  96. {
  97. b = new byte[l];
  98. ms.Read(b, 0, l); done += l;
  99. list.Add(b);
  100. addempty = false;
  101. }
  102. }
  103. if (addempty) list.Add(Constant.EmptyBytes);
  104. }
  105. else break;
  106. }
  107. }
  108. }
  109. return list;
  110. }
  111. /// <summary>封装多个字节数组。</summary>
  112. public static byte[] FromList(List<byte[]> argList)
  113. {
  114. if (argList == null) return Constant.EmptyBytes;
  115. var count = argList.Count;
  116. var ms = new MemoryStream();
  117. var sl = GetBytes(count);
  118. ms.Write(sl, 0, sl.Length);
  119. for (int i = 0; i < count; i++)
  120. {
  121. var len = GetBytes(argList[i].Length);
  122. ms.Write(len, 0, len.Length);
  123. ms.Write(argList[i], 0, argList[i].Length);
  124. }
  125. var bs = ms.ToArray();
  126. ms.Dispose();
  127. return bs;
  128. }
  129. /// <summary>Int32 -> Byte[]</summary>
  130. private static byte[] GetBytes(int argValue)
  131. {
  132. const int t3 = 256 * 256 * 256;
  133. const int t2 = 256 * 256;
  134. const int t1 = 256;
  135. byte[] vbs = { 0, 0, 0, 0 };
  136. if (argValue >= 0)
  137. {
  138. int vint = argValue;
  139. vbs[0] = (byte)(vint / t3);
  140. vint = vint % t3;
  141. vbs[1] = (byte)(vint / t2);
  142. vint = vint % t2;
  143. vbs[2] = (byte)(vint / t1);
  144. vint = vint % t1;
  145. vbs[3] = (byte)(vint);
  146. }
  147. else
  148. {
  149. int vminusint = Math.Abs(argValue + 1);
  150. var vminusbs = GetBytes(vminusint);
  151. vbs[0] = (byte)(255 - vminusbs[0]);
  152. vbs[1] = (byte)(255 - vminusbs[1]);
  153. vbs[2] = (byte)(255 - vminusbs[2]);
  154. vbs[3] = (byte)(255 - vminusbs[3]);
  155. }
  156. return vbs;
  157. }
  158. /// <summary>Byte[] -> Int32</summary>
  159. private static Int32 GetInt32(byte[] argValue)
  160. {
  161. if (argValue.Length == 4)
  162. {
  163. const int t3 = 256 * 256 * 256;
  164. const int t2 = 256 * 256;
  165. const int t1 = 256;
  166. if (argValue[0] <= 127)
  167. {
  168. int[] vis = { 0, 0, 0, 0 };
  169. vis[0] = argValue[0] * t3;
  170. vis[1] = argValue[1] * t2;
  171. vis[2] = argValue[2] * t1;
  172. vis[3] = argValue[3];
  173. int vr = vis[0] + vis[1] + vis[2] + vis[3];
  174. return vr;
  175. }
  176. else
  177. {
  178. if ((argValue[0] == 128) && (argValue[1] == 0) && (argValue[2] == 0) && (argValue[3] == 0))
  179. {
  180. return int.MinValue;
  181. }
  182. else
  183. {
  184. var vbs = new byte[4];
  185. vbs[0] = (byte)(255 - argValue[0]);
  186. vbs[1] = (byte)(255 - argValue[1]);
  187. vbs[2] = (byte)(255 - argValue[2]);
  188. vbs[3] = (byte)(255 - argValue[3]);
  189. int vminusint = 0 - 1 - GetInt32(vbs);
  190. return vminusint;
  191. }
  192. }
  193. }
  194. return 0;
  195. }
  196. /// <summary>Byte[] -> Base64</summary>
  197. public static string ToBase64(byte[] argBytes)
  198. {
  199. var vnull = "";
  200. if (argBytes.Length < 1) return vnull;
  201. try { return Convert.ToBase64String(argBytes); }
  202. catch { return vnull; }
  203. }
  204. /// <summary>Base64 -> Byte[]</summary>
  205. public static byte[] FromBase64(string argBase64)
  206. {
  207. var vnull = Constant.EmptyBytes;
  208. if (string.IsNullOrEmpty(argBase64)) return vnull;
  209. try { return Convert.FromBase64String(argBase64); }
  210. catch { return vnull; }
  211. }
  212. /// <summary>创建数组,元素值为零。</summary>
  213. public static byte[] ZeroArray(int argCount)
  214. {
  215. if (argCount < 1) return Constant.EmptyBytes;
  216. var ba = new Byte[argCount];
  217. for (int i = 0; i < argCount; i++) ba[i] = 0;
  218. return ba;
  219. }
  220. }
  221. }