你的位置:首页 > ASP.net教程

[ASP.net教程]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 转换为 0102107 /// </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否则false205 /// </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转换为byte221 /// </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转换为byte274 /// </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 /// 将四个字节合成为一个int363 /// </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     /// 将八个字节合成为一个ulong394     /// </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的某个位是否为1435 /// </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 /// 将两个字节转换为一个short545 /// </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     /// 将两个字节转换为一个short555     /// </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  /// 将四个字节转换为int564  /// </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   }