王安禹的blog

导航

byte数据的常用操作函数[转发]

  1 /// <summary>
  2 /// 本类提供了对byte数据的常用操作函数
  3 /// </summary>
  4 public class ByteUtil
  5 {
  6 private static char[] HEX_CHARS = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  7 private static byte[] BITS = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
  8 
  9 
 10 /// <summary>
 11 /// 将字节数组转换为HEX形式的字符串, 使用指定的间隔符
 12 /// </summary>
 13 public static string ByteToHex(byte[] buf, string separator)
 14 {
 15 System.Text.StringBuilder sb = new System.Text.StringBuilder();
 16 for(int i = 0;i < buf.Length;i++)
 17 {
 18 if (i > 0)
 19 {
 20 sb.Append(separator);
 21 }
 22 sb.Append(HEX_CHARS[buf[i] >> 4]).Append(HEX_CHARS[buf[i] & 0x0F]);
 23 }
 24 return sb.ToString();
 25 }
 26 
 27 
 28 
 29 
 30 /// <summary>
 31 /// 将字节数组转换为HEX形式的字符串, 使用指定的间隔符
 32 /// </summary>
 33 public static string ByteToHex(byte[] buf, char c)
 34 {
 35 System.Text.StringBuilder sb = new System.Text.StringBuilder();
 36 for(int i = 0;i < buf.Length;i++)
 37 {
 38 if (i > 0)
 39 {
 40 sb.Append(c);
 41 }
 42 sb.Append(HEX_CHARS[buf[i] >> 4]).Append(HEX_CHARS[buf[i] & 0x0F]);
 43 }
 44 return sb.ToString();
 45 }
 46 
 47 
 48         /// <summary>
 49         /// 判断字节数组前几位是否符合一定规则
 50         /// </summary>
 51         /// <param name="data">需要判断的字节数组</param>
 52         /// <param name="pattern">匹配规则</param>
 53         /// <returns>如果匹配返回true</returns>
 54         public static bool IsMatch(byte[] data, params byte[] pattern)
 55         {
 56             if (data == null || data.Length < pattern.Length)
 57                 return false;
 58 
 59 
 60             for(int i = 0;i < pattern.Length;i++)
 61             {
 62                 if (data[i] != pattern[i])
 63                     return false;
 64             }
 65             return true;
 66         }
 67 
 68 
 69         /// <summary>
 70         /// 判断指定字节是否为列举的某个值
 71         /// </summary>
 72         /// <param name="value">需要判断的值</param>
 73         /// <param name="choice">可能值</param>
 74         /// <returns>如果与任一个可能值相等则返回true</returns>
 75         public static bool IsMatch(byte value, params byte[] choice)
 76         {
 77             if (choice == null || choice.Length == 0)
 78                 return false;
 79 
 80 
 81             foreach(byte item in choice)
 82             {
 83                 if (item == value)
 84                     return true;
 85             }
 86             return false;
 87         }
 88 
 89 
 90 
 91 
 92         /// <summary>
 93         /// 将字节数组转换为HEX形式的字符串, 没有间隔符
 94         /// </summary>
 95         public static string ByteToHex(byte[] buf)
 96 {
 97 return ByteToHex(buf, string.Empty);
 98 }
 99 
100 
101 
102 
103 /// <summary>
104 /// 将字节数组转换为HEX形式的字符串
105 /// 转换后的字符串长度为字节数组长度的两倍
106 /// 如: 1, 2 转换为 0102
107 /// </summary>
108 public static string ByteToHex(byte b)
109 {
110 return string.Empty + HEX_CHARS[b >> 4] + HEX_CHARS[b & 0x0F];
111 }
112 
113 
114 
115 
116 /// <summary>
117 /// 将字节流信息转换为HEX字符串
118 /// </summary>
119 public static string DumpBytes(byte[] bytes)
120 {
121 return DumpBytes(bytes, 0, bytes.Length);
122 }
123 
124 
125 /// <summary>
126         /// 将字节流信息转换为HEX字符串
127 /// </summary>
128 public static string DumpBytes(byte[] bytes, int offset, int len)
129 {
130    StringBuilder buf = new StringBuilder();
131 for(int i = 0;i < len;i++)
132 {
133 if (i == 0 || i % 16 == 0)
134                     buf.AppendLine();
135    
136 buf.Append(ByteToHex(bytes[i + offset]));
137                 buf.Append(' ');
138 }
139             buf.AppendLine();
140             return buf.ToString();
141 }
142 
143 
144 
145 
146 /// <summary>
147 /// 计算字节块的模256校验和
148 /// </summary>
149 public static byte SumBytes(byte[] bytes, int offset, int len)
150 {
151 int sum = 0;
152 for(int i = 0;i < len;i++)
153 {
154 sum += bytes[i + offset];
155 if (sum >= 256)
156 {
157 sum = sum % 256;
158 }
159 }
160 return (byte)sum;
161 }
162 
163 
164 /// <summary>
165 /// 计算字节块的模256双字节校验和(低位在前)
166 /// </summary>
167 public static byte[] Sum2Bytes(byte[] bytes, int offset, int len)
168 {
169 int sum = 0;
170 for(int i = 0;i < len;i++)
171 sum += bytes[i + offset];
172             return new byte[] { (byte)(sum % 256), (byte)(sum / 256) };
173 }
174 
175 
176 /// <summary>
177 /// 计算字节块的异或校验和
178 /// </summary>
179 public static byte XorSumBytes(byte[] bytes, int offset, int len)
180 {
181 byte sum = bytes[0 + offset];
182 for(int i = 1;i < len;i++)
183 {
184 sum = (byte)(sum ^ bytes[i + offset]);
185 }
186 return sum;
187 }
188 
189 
190 
191 
192 /// <summary>
193 /// 计算字节块的异或校验和
194 /// </summary>
195 public static byte XorSumBytes(byte[] bytes)
196 {
197 return XorSumBytes(bytes, 0, bytes.Length);
198 }
199 
200 
201 
202 
203 /// <summary>
204 /// 比较两个字节块是否相等。相等返回true否则false
205 /// </summary>
206 public static bool CompareBytes(byte[] bytes1, int offset1, byte[] bytes2, int offset2, int len)
207 {
208 for(int i = 0;i < len;i++)
209 {
210 if (bytes1[i + offset1] != bytes2[i + offset2])
211 {
212 return false;
213 }
214 }
215 return true;
216 }
217 
218 
219 /// <summary>
220 /// 将两个字符的hex转换为byte
221 /// </summary>
222 public static byte HexToByte(char[] hex, int offset)
223 {
224 byte result = 0;
225 for(int i = 0;i < 2;i++)
226 {
227 char c = hex[i + offset];
228 byte b = 0;
229 switch (c)
230 {
231 case '0':
232 case '1':
233 case '2':
234 case '3':
235 case '4':
236 case '5':
237 case '6':
238 case '7':
239 case '8':
240 case '9':
241 b = (byte)(c - '0');
242 break;
243 case 'A':
244 case 'B':
245 case 'C':
246 case 'D':
247 case 'E':
248 case 'F':
249 b = (byte)(10 + c - 'A');
250 break;
251 case 'a':
252 case 'b':
253 case 'c':
254 case 'd':
255 case 'e':
256 case 'f':
257 b = (byte)(10 + c - 'a');
258 break;
259 }
260 if (i == 0)
261 {
262 b = (byte)(b * 16);
263 }
264 result += b;
265 }
266 
267 
268 return result;
269 }
270 
271 
272 /// <summary>
273 /// 将两个字符的hex转换为byte
274 /// </summary>
275 public static byte HexToByte(byte[] hex, int offset)
276 {
277 char[] chars = {(char)hex[offset], (char)hex[offset + 1]};
278 return HexToByte(chars, 0);
279 }
280 
281 
282         /// <summary>
283         /// 转换16进制字符串为字节数组
284         /// <param name="hex">有分隔或无分隔的16进制字符串,如“AB CD EF 12 34...”或“ABCDEF1234...”</param>
285         /// <param name="dot">任意分隔字符,但不能是16进制字符</param>
286         /// <returns>字节数组</returns>
287         /// </summary>
288         public static byte[] HexToByte(string hex, params char[] dot) {
289             char[] ca = new char[2];
290             List<byte> list = new List<byte>();
291             for (int i = 0, n = 0; i < hex.Length; i++) {
292                 if (Array.IndexOf<char>(dot, hex[i]) >= 0) {
293                     continue;
294                 }
295 
296 
297                 switch (++n) {
298                     case 1:
299                         ca[0] = hex[i];
300                         break;
301 
302 
303                     case 2:
304                         ca[1] = hex[i];
305                         list.Add(ByteUtil.HexToByte(ca, 0));
306                         n = 0;
307                         break;
308                 }
309             }
310 
311 
312             return list.ToArray();
313         }
314 
315 
316 /// <summary>
317 /// 将uint变量分解为四个字节。高位在前。
318 /// </summary>
319 public static void UintToBytes(uint i, byte[] bytes, int offset)
320 {
321 bytes[offset] = (byte)((i & 0xFF000000) >> 24);
322 bytes[offset + 1] = (byte)((i & 0x00FF0000) >> 16);
323 bytes[offset + 2] = (byte)((i & 0x0000FF00) >> 8);
324 bytes[offset + 3] = (byte)(i & 0x000000FF);
325 }
326 
327 
328         /// <summary>
329         /// 将uint变量分解为四个字节。高位在前。
330         /// </summary>
331         public static byte[] UintToBytes(uint i)
332         {
333             byte[] bytes = new byte[4];
334             bytes[0] = (byte)((i & 0xFF000000) >> 24);
335             bytes[1] = (byte)((i & 0x00FF0000) >> 16);
336             bytes[2] = (byte)((i & 0x0000FF00) >> 8);
337             bytes[3] = (byte)(i & 0x000000FF);
338             return bytes;
339         }
340 
341 
342         /// <summary>
343         /// 将int变量分解为四个字节。高位在前。
344         /// </summary>
345         public static byte[] IntToBytes(int i)
346         {
347             byte[] data = BitConverter.GetBytes(i);
348             Array.Reverse(data);
349             return data;
350 
351 
352             //byte[] bytes = new byte[4];
353             //bytes[0] = (byte)((i & 0xFF000000) >> 24);
354             //bytes[1] = (byte)((i & 0x00FF0000) >> 16);
355             //bytes[2] = (byte)((i & 0x0000FF00) >> 8);
356             //bytes[3] = (byte)(i & 0x000000FF);
357             //return bytes;
358         }
359 
360 
361 /// <summary>
362 /// 将四个字节合成为一个int
363 /// </summary>
364 public static uint BytesToUint(byte[] bytes, int offset)
365 {
366 uint a = ((uint)bytes[offset]) << 24;
367 uint b = ((uint)bytes[offset + 1]) << 16;
368 uint c = ((uint)bytes[offset + 2]) << 8;
369 uint d = bytes[offset + 3];
370 return a + b + c + d;
371 }
372 
373 
374         /// <summary>
375         /// 将ulong变量分解为八个字节。高位在前。
376         /// </summary>
377         public static byte[] UlongToBytes(ulong i)
378         {
379             byte[] bytes = new byte[8];
380             bytes[0] = (byte)((i & 0xFF00000000000000) >> 56);
381             bytes[1] = (byte)((i & 0x00FF000000000000) >> 48);
382             bytes[2] = (byte)((i & 0x0000FF0000000000) >> 40);
383             bytes[3] = (byte)((i & 0x000000FF00000000) >> 32);
384             bytes[4] = (byte)((i & 0x00000000FF000000) >> 24);
385             bytes[5] = (byte)((i & 0x0000000000FF0000) >> 16);
386             bytes[6] = (byte)((i & 0x000000000000FF00) >> 8);
387             bytes[7] = (byte)(i & 0x00000000000000FF);
388             return bytes;
389         }
390 
391 
392         /// <summary>
393         /// 将八个字节合成为一个ulong
394         /// </summary>
395         public static ulong BytesToUlong(byte[] bytes, int offset)
396         {
397             ulong a = ((ulong)bytes[offset]) << 56;
398             ulong b = ((ulong)bytes[offset + 1]) << 48;
399             ulong c = ((ulong)bytes[offset + 2]) << 40;
400             ulong d = ((ulong)bytes[offset + 3]) << 32;
401             ulong e = ((ulong)bytes[offset + 4]) << 24;
402             ulong f = ((ulong)bytes[offset + 5]) << 16;
403             ulong g = ((ulong)bytes[offset + 6]) << 8;
404             ulong h = bytes[offset + 7];
405             return a + b + c + d + e + f + g + h;
406         }
407 
408 
409 
410 
411 /// <summary>
412 /// 设置某个字节的指定位
413 /// </summary>
414 /// <param name="b">需要设置的字节</param>
415 /// <param name="pos">1-8, 1表示最低位, 8表示最高位</param>
416 /// <param name="on">true表示设置1, false表示设置0</param>
417 public static void ByteSetBit(ref byte b, int pos, bool on)
418 {
419 int temp = BITS[pos - 1];
420 
421 
422 if (!on)
423 {
424 //取反
425 temp = temp ^ 0xFF;
426 }
427 
428 
429 b = (byte)(on?(b | temp):(b & temp));
430 }
431 
432 
433 /// <summary>
434 /// 判断某个byte的某个位是否为1
435 /// </summary>
436         /// <param name="pos">第几位,大于等于1</param>
437 public static bool ByteGetBit(byte b, int pos)
438 {
439 int temp = BITS[pos - 1];
440 return (b & temp) != 0;
441 }
442 
443 
444 
445 
446 /// <summary>
447 /// 设置双比特值
448 /// </summary>
449 /// <param name="b">需要设置的字节</param>
450 /// <param name="low">低位, 1-7</param>
451 /// <param name="val">值,0-3</param>
452 /// <returns></returns>
453 public static void ByteSetBitPair(ref byte b, int low, int val)
454 {
455 if (low < 1 || low > 7)
456 {
457 throw new ArgumentException(string.Format("无效的low值:{0}", low));
458 }
459 
460 
461 switch(val)
462 {
463 case 0:
464 {
465 ByteUtil.ByteSetBit(ref b, low, false);
466 ByteUtil.ByteSetBit(ref b, low + 1, false);
467 break;
468 }
469 case 1:
470 {
471 ByteUtil.ByteSetBit(ref b, low, true);
472 ByteUtil.ByteSetBit(ref b, low + 1, false);
473 break;
474 }
475 case 2:
476 {
477 ByteUtil.ByteSetBit(ref b, low, false);
478 ByteUtil.ByteSetBit(ref b, low + 1, true);
479 break;
480 }
481 case 3:
482 {
483 ByteUtil.ByteSetBit(ref b, low, true);
484 ByteUtil.ByteSetBit(ref b, low + 1, true);
485 break;
486 }
487 default:
488 {
489 throw new ArgumentException(string.Format("无效的val值:{0}", val));
490 }
491 }
492 }
493 
494 
495 
496 
497 /// <summary>
498 /// 读取双比特值
499 /// </summary>
500 /// <param name="b">需要读取的字节</param>
501 /// <param name="low">低位, 0-6</param>
502 /// <returns>0-3</returns>
503 public static byte ByteGetBitPair(byte b, int low)
504 {
505 if (low < 0 || low > 7)
506 {
507 throw new ArgumentException(string.Format("无效的low值:{0}", low));
508 }
509 
510 
511 int x = 0;
512 x += ByteUtil.ByteGetBit(b, low)?1:0;
513 x += ByteUtil.ByteGetBit(b, low + 1)?2:0;
514 
515 
516 return (byte)x;
517 }
518 
519 
520 /// <summary>
521 /// 将short转换为两个字节
522 /// </summary>
523 /// <param name="s"></param>
524 /// <returns></returns>
525 public static byte[] ShortToByte(short s)
526 {
527 return UshortToByte((ushort)s);
528 }
529 
530 
531 /// <summary>
532 /// 将ushort转换为两个字节
533 /// </summary>
534 public static byte[] UshortToByte(ushort u)
535 {
536 return new byte[]{
537 (byte)(u >> 8),
538 (byte)(u & 0x00FF)
539 };
540 }
541 
542 
543 /// <summary>
544 /// 将两个字节转换为一个short
545 /// </summary>
546 public static short BytesToShort(byte[] data, int offset)
547 {
548 short a = data[offset], b = data[offset + 1];
549 return (short)((a << 8) + b);
550 }
551 
552 
553         /// <summary>
554         /// 将两个字节转换为一个short
555         /// </summary>
556         public static ushort BytesToUshort(byte[] data, int offset)
557         {
558             ushort a = data[offset], b = data[offset + 1];
559             return (ushort)((a << 8) + b);
560         }
561    
562    /// <summary>
563    /// 将四个字节转换为int
564    /// </summary>
565    /// <param name="data"></param>
566    /// <param name="offset"></param>
567    /// <returns></returns>
568    public static int BytesToInt(byte[] data, int offset)
569    {
570             return (data[offset] << 24) + (data[offset + 1] << 16) + (data[offset + 2] << 8) + data[offset + 3];
571    }
572 
573 
574         /// <summary>
575         /// 将guid字符串转换为等价的16维字节数组
576         /// </summary>
577         public static byte[] GuidToBytes(string s)
578         {
579             byte[] guid = new byte[16];
580             char[] hex = s.Replace("-", string.Empty).Replace(" ", string.Empty).ToCharArray();
581             for (int i = 0; i < 32; i += 2)
582             {
583                 guid[i / 2] = ByteUtil.HexToByte(hex, i);
584             }
585             return guid;
586         }
587 
588 
589         /// <summary>
590         /// CRC16校验表
591         /// </summary>
592         static ushort[] wCRCTalbeAbs = {0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400};
593 
594 
595         /// <summary>
596         /// 计数字节块的CRC16校验值
597         /// </summary>
598         public static int CRC16Bytes(byte[] bytes, int offset, int len)
599         {
600                 int wCRC = 0xFFFF;
601                 byte chChar;
602 
603 
604                 for (int i = offset; i < len; i++)
605                 {
606                         chChar = bytes[i];
607                         wCRC = wCRCTalbeAbs[(chChar ^ wCRC) & 15] ^ (wCRC >> 4);
608                         wCRC = wCRCTalbeAbs[((chChar >> 4) ^ wCRC) & 15] ^ (wCRC >> 4);
609                 }
610 
611 
612                 return wCRC;
613         }
614 
615 
616         /// <summary>
617         /// 字节格式化,将字节转换为字节、KB、MB、GB显示
618         /// </summary>
619         /// <param name="bytes">字节数</param>
620         /// <returns>格式化后的字符串</returns>
621         public static string ByteFormater(long bytes)
622         {
623             const long KB = 1024;
624             const long MB = 1024 * 1024;
625             const long GB = 1024 * 1024 * 1024;
626 
627 
628             if (bytes >= GB)
629             {
630                 double result = bytes * 1.0 / GB;
631                 return result.ToString("#,##0.0") + "GB";
632             }
633             if (bytes >= MB)
634             {
635                 double result = bytes * 1.0 / MB;
636                 return result.ToString("#,##0.0") + "MB";
637             }
638             if (bytes >= KB)
639             {
640                 double result = bytes * 1.0 / KB;
641                 return result.ToString("#,##0.0") + "KB";
642             }
643             return bytes.ToString("#,##0") + "字节";
644         }
645     }

 

posted on 2016-06-13 16:34  王安禹的blog  阅读(3969)  评论(0编辑  收藏  举报