用C#实现的几种常用数据校验方法整理(CRC校验;LRC校验;BCC校验;累加和校验)

用C#实现的几种常用数据校验方法整理(CRC校验;LRC校验;BCC校验;累加和校验)

CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似的算法,以保证数据传输的正确性和完整性。
/// CRC算法参数模型解释:
/// NAME:参数模型名称。
///WIDTH:宽度,即CRC比特数。
/// POLY:生成项的简写,以16进制表示。例如:CRC-32即是0x04C11DB7,忽略了最高位的”1″,即完整的生成项是0x104C11DB7。
///INIT:这是算法开始时寄存器(crc)的初始化预置值,十六进制表示。
///REFIN:待测数据的每个字节是否按位反转,True或False。
/// REFOUT:在计算后之后,异或输出之前,整个数据是否按位反转,True或False。
/// XOROUT:计算结果与此参数异或后得到最终的CRC值。

/// **********************************************************************
/// Name: CRC-4/ITU    x4+x+1
/// Poly: 0x03
/// Init: 0x00
/// Refin: true
/// Refout: true
/// Xorout: 0x00
///*************************************************************************
public static byte[] Crc1(byte[] buffer, int start = 0, int len = 0)
{
if (buffer == null || buffer.Length == 0) return null;
if (start < 0) return null;
if (len == 0) len = buffer.Length – start;
int length = start + len;
if (length > buffer.Length) return null;
byte crc = 0;// Initial value
for (int i = start; i < length; i++)
{
crc ^= buffer[i];
for (int j = 0; j < 8; j++)
{
if ((crc & 1) > 0)
crc = (byte)((crc >> 1) ^ 0x0C);//0x0C = (reverse 0x03)>>(8-4)
else
crc = (byte)(crc >> 1);
}
}
return new byte[] { crc };
}
/// **********************************************************************
/// Name: CRC-5/EPC    x5+x3+1
/// Poly: 0x09
/// Init: 0x09
/// Refin: false
/// Refout: false
/// Xorout: 0x00
///*************************************************************************
public static byte[] Crc2(byte[] buffer, int start = 0, int len = 0)
{
if (buffer == null || buffer.Length == 0) return null;
if (start < 0) return null;
if (len == 0) len = buffer.Length – start;
int length = start + len;
if (length > buffer.Length) return null;
byte crc = 0x48;// Initial value: 0x48 = 0x09<<(8-5)
for (int i = start; i < length; i++)
{
crc ^= buffer[i];
for (int j = 0; j < 8; j++)
{
if ((crc & 0x80) > 0)
crc = (byte)((crc << 1) ^ 0x48);// 0x48 = 0x09<<(8-5)
else
crc = (byte)(crc << 1);
}
}
return new byte[] { (byte)(crc >> 3) };
}
/// **********************************************************************
/// Name: CRC-5/ITU    x5+x4+x2+1
/// Poly: 0x15
/// Init: 0x00
/// Refin: true
/// Refout: true
/// Xorout: 0x00
///*************************************************************************
public static byte[] Crc3(byte[] buffer, int start = 0, int len = 0)
{
if (buffer == null || buffer.Length == 0) return null;
if (start < 0) return null;
if (len == 0) len = buffer.Length – start;
int length = start + len;
if (length > buffer.Length) return null;
byte crc = 0;// Initial value
for (int i = start; i < length; i++)
{
crc ^= buffer[i];
for (int j = 0; j < 8; j++)
{
if ((crc & 1) > 0)
crc = (byte)((crc >> 1) ^ 0x15);// 0x15 = (reverse 0x15)>>(8-5)
else
crc = (byte)(crc >> 1);
}
}
return new byte[] { crc  };
}
/// **********************************************************************
/// Name: CRC-5/USB    x5+x2+1
/// Poly: 0x05
/// Init: 0x1F
/// Refin: true
/// Refout: true
/// Xorout: 0x1F
///*************************************************************************
public static byte[] Crc4(byte[] buffer, int start = 0, int len = 0)
{
if (buffer == null || buffer.Length == 0) return null;
if (start < 0) return null;
if (len == 0) len = buffer.Length – start;
int length = start + len;
if (length > buffer.Length) return null;
byte crc = 0x1F;// Initial value
for (int i = start; i < length; i++)
{
crc ^= buffer[i];
for (int j = 0; j < 8; j++)
{
if ((crc & 1) > 0)
crc = (byte)((crc >> 1) ^ 0x14);// 0x14 = (reverse 0x05)>>(8-5)
else
crc = (byte)(crc >> 1);
}
}
return new byte[] {(byte)( crc ^ 0x1F)  };
}
/// **********************************************************************
/// Name: CRC-6/ITU    x6+x+1
/// Poly: 0x03
/// Init: 0x00
/// Refin: true
/// Refout: true
/// Xorout: 0x00
///*************************************************************************
public static byte[] Crc5(byte[] buffer, int start = 0, int len = 0)
{
if (buffer == null || buffer.Length == 0) return null;
if (start < 0) return null;
if (len == 0) len = buffer.Length – start;
int length = start + len;
if (length > buffer.Length) return null;
byte crc = 0;// Initial value
for (int i = start; i < length; i++)
{
crc ^= buffer[i];
for (int j = 0; j < 8; j++)
{
if ((crc & 1) > 0)
crc = (byte)((crc >> 1) ^ 0x30);// 0x30 = (reverse 0x03)>>(8-6)
else
crc = (byte)(crc >> 1);
}
}
return new byte[] { crc  };
}
/// **********************************************************************
/// Name: CRC-7/MMC    x7+x3+1
/// Poly: 0x09
/// Init: 0x00
/// Refin: false
/// Refout: false
/// Xorout: 0x00
///*************************************************************************
public static byte[] Crc6(byte[] buffer, int start = 0, int len = 0)
{
if (buffer == null || buffer.Length == 0) return null;
if (start < 0) return null;
if (len == 0) len = buffer.Length – start;
int length = start + len;
if (length > buffer.Length) return null;
byte crc = 0;// Initial value
for (int i = start; i < length; i++)
{
crc ^= buffer[i];
for (int j = 0; j < 8; j++)
{
if ((crc & 0x80) > 0)
crc = (byte)((crc << 1) ^ 0x12);// 0x12 = 0x09<<(8-7)
else
crc = (byte)(crc << 1);
}
}
return new byte[] { (byte)(crc >> 1)  };
}
/// **********************************************************************
/// Name: CRC8    x8+x2+x+1
177     /// Poly: 0x07
178     /// Init: 0x00
179     /// Refin: false
180     /// Refout: false
181     /// Xorout: 0x00
182     ///*************************************************************************
183         public static byte[] Crc7(byte[] buffer, int start = 0, int len = 0)
184         {
185             if (buffer == null || buffer.Length == 0) return null;
186             if (start < 0) return null;
187             if (len == 0) len = buffer.Length – start;
188             int length = start + len;
189             if (length > buffer.Length) return null;
190             byte crc = 0;// Initial value
191             for (int i = start; i < length; i++)
192             {
193                 crc ^= buffer[i];
194                 for (int j = 0; j < 8; j++)
195                 {
196                     if ((crc & 0x80) > 0)
197                         crc = (byte)((crc << 1) ^ 0x07);
198                     else
199                         crc = (byte)(crc << 1);
200                 }
201             }
202             return new byte[] { crc  };
203         }
204     /// **********************************************************************
205     /// Name: CRC-8/ITU    x8+x2+x+1
206     /// Poly: 0x07
207     /// Init: 0x00
208     /// Refin: false
209     /// Refout: false
210     /// Xorout: 0x55
211     ///*************************************************************************
212         public static byte[] Crc8(byte[] buffer, int start = 0, int len = 0)
213         {
214             if (buffer == null || buffer.Length == 0) return null;
215             if (start < 0) return null;
216             if (len == 0) len = buffer.Length – start;
217             int length = start + len;
218             if (length > buffer.Length) return null;
219             byte crc = 0;// Initial value
220             for (int i = start; i < length; i++)
221             {
222                 crc ^= buffer[i];
223                 for (int j = 0; j < 8; j++)
224                 {
225                     if ((crc & 0x80) > 0)
226                         crc = (byte)((crc << 1) ^ 0x07);
227                     else
228                         crc = (byte)(crc << 1);
229                 }
230             }
231             return new byte[] { (byte)(crc ^ 0x55)  };
232         }
233     /// **********************************************************************
234     /// Name: CRC-8/MAXIM    x8+x5+x4+1
235     /// Poly: 0x31
236     /// Init: 0x00
237     /// Refin: true
238     /// Refout: true
239     /// Xorout: 0x00
240     ///*************************************************************************
241         public static byte[] Crc9(byte[] buffer, int start = 0, int len = 0)
242         {
243             if (buffer == null || buffer.Length == 0) return null;
244             if (start < 0) return null;
245             if (len == 0) len = buffer.Length – start;
246             int length = start + len;
247             if (length > buffer.Length) return null;
248             byte crc = 0;// Initial value
249             for (int i = start; i < length; i++)
250             {
251                 crc ^= buffer[i];
252                 for (int j = 0; j < 8; j++)
253                 {
254                     if ((crc & 1) > 0)
255                         crc = (byte)((crc >> 1) ^ 0x8C);// 0x8C = reverse 0x31
256                     else
257                         crc = (byte)(crc >> 1);
258                 }
259             }
260             return new byte[] { crc  };
261         }
262     /// **********************************************************************
263     /// Name: CRC-8/ROHC    x8+x2+x+1
264     /// Poly: 0x07
265     /// Init: 0xFF
266     /// Refin: true
267     /// Refout: true
268     /// Xorout: 0x00
269     ///*************************************************************************
270         public static byte[] Crc10(byte[] buffer, int start = 0, int len = 0)
271         {
272             if (buffer == null || buffer.Length == 0) return null;
273             if (start < 0) return null;
274             if (len == 0) len = buffer.Length – start;
275             int length = start + len;
276             if (length > buffer.Length) return null;
277             byte crc = 0xFF;// Initial value
278             for (int i = start; i < length; i++)
279             {
280                 crc ^= buffer[i];
281                 for (int j = 0; j < 8; j++)
282                 {
283                     if ((crc & 1) > 0)
284                         crc = (byte)((crc >> 1) ^ 0xE0);// 0xE0 = reverse 0x07
285                     else
286                         crc = (byte)(crc >> 1);
287                 }
288             }
289             return new byte[] { crc  };
290         }
291     /// Z1协议校验码计算
292         static byte[] table = { 0x00, 0x1C, 0x38, 0x24, 0x70, 0x6C, 0x48, 0x54, 0xE0, 0xFC,
293                                 0xD8, 0xC4, 0x90, 0x8C, 0xA8, 0xB4, 0xDC, 0xC0, 0xE4, 0xF8,
294                                 0xAC, 0xB0, 0x94, 0x88, 0x3C, 0x20, 0x04, 0x18, 0x4C, 0x50,
295                                 0x74, 0x68, 0xA4, 0xB8, 0x9C, 0x80, 0xD4, 0xC8, 0xEC, 0xF0,
296                                 0x44, 0x58, 0x7C, 0x60, 0x34, 0x28, 0x0C, 0x10, 0x78, 0x64,
297                                 0x40, 0x5C, 0x08, 0x14, 0x30, 0x2C, 0x98, 0x84, 0xA0, 0xBC,
298                                 0xE8, 0xF4, 0xD0, 0xCC, 0x54, 0x48, 0x6C, 0x70, 0x24, 0x38,
299                                 0x1C, 0x00, 0xB4, 0xA8, 0x8C, 0x90, 0xC4, 0xD8, 0xFC, 0xE0,
300                                 0x88, 0x94, 0xB0, 0xAC, 0xF8, 0xE4, 0xC0, 0xDC, 0x68, 0x74,
301                                 0x50, 0x4C, 0x18, 0x04, 0x20, 0x3C, 0xF0, 0xEC, 0xC8, 0xD4,
302                                 0x80, 0x9C, 0xB8, 0xA4, 0x10, 0x0C, 0x28, 0x34, 0x60, 0x7C,
303                                 0x58, 0x44, 0x2C, 0x30, 0x14, 0x08, 0x5C, 0x40, 0x64, 0x78,
304                                 0xCC, 0xD0, 0xF4, 0xE8, 0xBC, 0xA0, 0x84, 0x98, 0xA8, 0xB4,
305                                 0x90, 0x8C, 0xD8, 0xC4, 0xE0, 0xFC, 0x48, 0x54, 0x70, 0x6C,
306                                 0x38, 0x24, 0x00, 0x1C, 0x74, 0x68, 0x4C, 0x50, 0x04, 0x18,
307                                 0x3C, 0x20, 0x94, 0x88, 0xAC, 0xB0, 0xE4, 0xF8, 0xDC, 0xC0,
308                                 0x0C, 0x10, 0x34, 0x28, 0x7C, 0x60, 0x44, 0x58, 0xEC, 0xF0,
309                                 0xD4, 0xC8, 0x9C, 0x80, 0xA4, 0xB8, 0xD0, 0xCC, 0xE8, 0xF4,
310                                 0xA0, 0xBC, 0x98, 0x84, 0x30, 0x2C, 0x08, 0x14, 0x40, 0x5C,
311                                 0x78, 0x64, 0xFC, 0xE0, 0xC4, 0xD8, 0x8C, 0x90, 0xB4, 0xA8,
312                                 0x1C, 0x00, 0x24, 0x38, 0x6C, 0x70, 0x54, 0x48, 0x20, 0x3C,
313                                 0x18, 0x04, 0x50, 0x4C, 0x68, 0x74, 0xC0, 0xDC, 0xF8, 0xE4,
314                                 0xB0, 0xAC, 0x88, 0x94, 0x58, 0x44, 0x60, 0x7C, 0x28, 0x34,
315                                 0x10, 0x0C, 0xB8, 0xA4, 0x80, 0x9C, 0xC8, 0xD4, 0xF0, 0xEC,
316                                 0x84, 0x98, 0xBC, 0xA0, 0xF4, 0xE8, 0xCC, 0xD0, 0x64, 0x78,
317                                 0x5C, 0x40, 0x14, 0x08, 0x2C, 0x30
318                               };
319         public static byte[] Crc11(byte[] buffer, int start = 0, int len = 0)
320         {
321             if (buffer == null || buffer.Length == 0) return null;
322             if (start < 0) return null;
323             if (len == 0) len = buffer.Length – start;
324             int length = start + len;
325             if (length > buffer.Length) return null;
326             int i;
327             byte crc = 0x00;
328             int tableIndex;
329             for (i = start; i < length; i++)
330             {
331                 tableIndex = crc ^ (buffer[i] & 0xFF);
332                 crc = table[tableIndex];
333             }
334             return new byte[] { crc };
335         }
336     /// **********************************************************************
337     /// Name: CRC-12    x16+x12+x5+1
338     /// Poly: 0x80
339     /// Init: 0x0000
340     /// Refin: true
341     /// Refout: true
342     /// Xorout: 0x0000
343     ///*************************************************************************
344         public static byte[] Crc12(byte[] buffer, int start = 0, int len = 0)
345         {
346             if (buffer == null || buffer.Length == 0) return null;
347             if (start < 0) return null;
348             if (len == 0) len = buffer.Length – start;
349             int length = start + len;
350             if (length > buffer.Length) return null;
351             ushort crc = 0;// Initial value
352             short iQ = 0, iR = 0;
353             for (int i = start; i < length; i++)
354             {
355                 // 多项式除法
356                 // 如果该位为1
357                 if ((buffer[i] & (0x80 >> iR)) > 0)
358                 {
359                     // 则在余数尾部添1否则添0
360                     crc |= 0x01;
361                 }
362                 // 如果12位除数中的最高位为1,则够除
363                 if (crc >= 0x1000)
364                 {
365                     crc ^= 0x180D;
366                 }
367                 crc <<= 1;
368                 iR++;
369                 if (8 == iR)
370                 {
371                     iR = 0;
372                     iQ++;
373                 }
374             }
375             // 对后面添加的12个0做处理
376             for (int i = 0; i < 12; i++)
377             {
378                 if (crc >= 0x1000)
379                 {
380                     crc ^= 0x180D;
381                 }
382                 crc <<= 1;
383             }
384             crc >>= 1;
385             byte[] ret = BitConverter.GetBytes(crc);
386             Array.Reverse(ret);
387             return ret;
388         }
389     /// **********************************************************************
390     /// Name: CRC-16/CCITT    x16+x12+x5+1
391     /// Poly: 0x1021
392     /// Init: 0x0000
393     /// Refin: true
394     /// Refout: true
395     /// Xorout: 0x0000
396     ///*************************************************************************
397         public static byte[] Crc13(byte[] buffer, int start = 0, int len = 0)
398         {
399             if (buffer == null || buffer.Length == 0) return null;
400             if (start < 0) return null;
401             if (len == 0) len = buffer.Length – start;
402             int length = start + len;
403             if (length > buffer.Length) return null;
404             ushort crc = 0;// Initial value
405             for (int i = start; i < length; i++)
406             {
407                 crc ^= buffer[i];
408                 for (int j = 0; j < 8; j++)
409                 {
410                     if ((crc & 1) > 0)
411                         crc = (ushort)((crc >> 1) ^ 0x8408);// 0x8408 = reverse 0x1021
412                     else
413                         crc = (ushort)(crc >> 1);
414                 }
415             }
416             byte[] ret = BitConverter.GetBytes(crc);
417             Array.Reverse(ret);
418             return ret;
419         }
420     /// **********************************************************************
421     /// Name: CRC-16/CCITT FALSE    x16+x12+x5+1
422     /// Poly: 0x1021
423     /// Init: 0xFFFF
424     /// Refin: false
425     /// Refout: false
426     /// Xorout: 0x0000
427     ///*************************************************************************
428         public static byte[] Crc14(byte[] buffer, int start = 0, int len = 0)
429         {
430             if (buffer == null || buffer.Length == 0) return null;
431             if (start < 0) return null;
432             if (len == 0) len = buffer.Length – start;
433             int length = start + len;
434             if (length > buffer.Length) return null;
435             ushort crc = 0xFFFF;// Initial value
436             for (int i = start; i < length; i++)
437             {
438                 crc ^= (ushort)(buffer[i] << 8);
439                 for (int j = 0; j < 8; j++)
440                 {
441                     if ((crc & 0x8000) > 0)
442                         crc = (ushort)((crc << 1) ^ 0x1021);
443                     else
444                         crc = (ushort)(crc << 1);
445                 }
446             }
447             byte[] ret = BitConverter.GetBytes(crc);
448             Array.Reverse(ret);
449             return ret;
450         }
451     /// **********************************************************************
452     /// Name: CRC-16/DNP    x16+x13+x12+x11+x10+x8+x6+x5+x2+1
453     /// Poly: 0x3D65
454     /// Init: 0x0000
455     /// Refin: true
456     /// Refout: true
457     /// Xorout: 0xFFFF
458     ///*************************************************************************
459         public static byte[] Crc15(byte[] buffer, int start = 0, int len = 0)
460         {
461             if (buffer == null || buffer.Length == 0) return null;
462             if (start < 0) return null;
463             if (len == 0) len = buffer.Length – start;
464             int length = start + len;
465             if (length > buffer.Length) return null;
466             ushort crc = 0;// Initial value
467             for (int i = start; i < length; i++)
468             {
469                 crc ^= buffer[i];
470                 for (int j = 0; j < 8; j++)
471                 {
472                     if ((crc & 1) > 0)
473                         crc = (ushort)((crc >> 1) ^ 0xA6BC);// 0xA6BC = reverse 0x3D65
474                     else
475                         crc = (ushort)(crc >> 1);
476                 }
477             }
478             byte[] ret = BitConverter.GetBytes((ushort)~crc);
479             Array.Reverse(ret);
480             return ret;
481         }
482     /// **********************************************************************
483     /// Name: CRC-16/IBM    x16+x15+x2+1
484     /// Poly: 0x8005
485     /// Init: 0x0000
486     /// Refin: true
487     /// Refout: true
488     /// Xorout: 0x0000
489     ///*************************************************************************
490         public static byte[] Crc16(byte[] buffer, int start = 0, int len = 0)
491         {
492             if (buffer == null || buffer.Length == 0) return null;
493             if (start < 0) return null;
494             if (len == 0) len = buffer.Length – start;
495             int length = start + len;
496             if (length > buffer.Length) return null;
497             ushort crc = 0;// Initial value
498             for (int i = start; i < length; i++)
499             {
500                 crc ^= buffer[i];
501                 for (int j = 0; j < 8; j++)
502                 {
503                     if ((crc & 1) > 0)
504                         crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005
505                     else
506                         crc = (ushort)(crc >> 1);
507                 }
508             }
509             byte[] ret = BitConverter.GetBytes(crc);
510             Array.Reverse(ret);
511             return ret;
512         }
513     /// **********************************************************************
514     /// Name: CRC-16/MAXIM    x16+x15+x2+1
515     /// Poly: 0x8005
516     /// Init: 0x0000
517     /// Refin: true
518     /// Refout: true
519     /// Xorout: 0xFFFF
520     ///*************************************************************************
521         public static byte[] Crc17(byte[] buffer, int start = 0, int len = 0)
522         {
523             if (buffer == null || buffer.Length == 0) return null;
524             if (start < 0) return null;
525             if (len == 0) len = buffer.Length – start;
526             int length = start + len;
527             if (length > buffer.Length) return null;
528             ushort crc = 0;// Initial value
529             for (int i = start; i < length; i++)
530             {
531                 crc ^= buffer[i];
532                 for (int j = 0; j < 8; j++)
533                 {
534                     if ((crc & 1) > 0)
535                         crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005
536                     else
537                         crc = (ushort)(crc >> 1);
538                 }
539             }
540             byte[] ret = BitConverter.GetBytes((ushort)~crc);
541             Array.Reverse(ret);
542             return ret;
543         }
544     /// **********************************************************************
545     /// Name: CRC-16/MODBUS    x16+x15+x2+1
546     /// Poly: 0x8005
547     /// Init: 0xFFFF
548     /// Refin: true
549     /// Refout: true
550     /// Xorout: 0x0000
551     ///*************************************************************************
552         public static byte[] Crc18(byte[] buffer, int start = 0, int len = 0)
553         {
554             if (buffer == null || buffer.Length == 0) return null;
555             if (start < 0) return null;
556             if (len == 0) len = buffer.Length – start;
557             int length = start + len;
558             if (length > buffer.Length) return null;
559             ushort crc = 0xFFFF;// Initial value
560             for (int i = start; i < length; i++)
561             {
562                 crc ^= buffer[i];
563                 for (int j = 0; j < 8; j++)
564                 {
565                     if ((crc & 1) > 0)
566                         crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005
567                     else
568                         crc = (ushort)(crc >> 1);
569                 }
570             }
571             byte[] ret = BitConverter.GetBytes(crc);
572             Array.Reverse(ret);
573             return ret;
574         }
575     /// **********************************************************************
576     /// Name: CRC-16/USB    x16+x15+x2+1
577     /// Poly: 0x8005
578     /// Init: 0xFFFF
579     /// Refin: true
580     /// Refout: true
581     /// Xorout: 0xFFFF
582     ///*************************************************************************
583         public static byte[] Crc19(byte[] buffer, int start = 0, int len = 0)
584         {
585             if (buffer == null || buffer.Length == 0) return null;
586             if (start < 0) return null;
587             if (len == 0) len = buffer.Length – start;
588             int length = start + len;
589             if (length > buffer.Length) return null;
590             ushort crc = 0xFFFF;// Initial value
591             for (int i = start; i < length; i++)
592             {
593                 crc ^= buffer[i];
594                 for (int j = 0; j < 8; j++)
595                 {
596                     if ((crc & 1) > 0)
597                         crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005
598                     else
599                         crc = (ushort)(crc >> 1);
600                 }
601             }
602             byte[] ret = BitConverter.GetBytes((ushort)~crc);
603             Array.Reverse(ret);
604             return ret;
605         }
606     /// **********************************************************************
607     /// Name: CRC-16/X25    x16+x12+x5+1
608     /// Poly: 0x1021
609     /// Init: 0xFFFF
610     /// Refin: true
611     /// Refout: true
612     /// Xorout: 0xFFFF
613     ///*************************************************************************
614         public static byte[] Crc20(byte[] buffer, int start = 0, int len = 0)
615         {
616             if (buffer == null || buffer.Length == 0) return null;
617             if (start < 0) return null;
618             if (len == 0) len = buffer.Length – start;
619             int length = start + len;
620             if (length > buffer.Length) return null;
621             ushort crc = 0xFFFF;// Initial value
622             for (int i = start; i < length; i++)
623             {
624                 crc ^= buffer[i];
625                 for (int j = 0; j < 8; j++)
626                 {
627                     if ((crc & 1) > 0)
628                         crc = (ushort)((crc >> 1) ^ 0x8408);// 0x8408 = reverse 0x1021
629                     else
630                         crc = (ushort)(crc >> 1);
631                 }
632             }
633             byte[] ret = BitConverter.GetBytes((ushort)~crc);
634             Array.Reverse(ret);
635             return ret;
636         }
637     /// **********************************************************************
638     /// Name: CRC-16/XMODEM    x16+x12+x5+1
639     /// Poly: 0x1021
640     /// Init: 0x0000
641     /// Refin: false
642     /// Refout: false
643     /// Xorout: 0x0000
644     ///*************************************************************************
645         public static byte[] Crc21(byte[] buffer, int start = 0, int len = 0)
646         {
647             if (buffer == null || buffer.Length == 0) return null;
648             if (start < 0) return null;
649             if (len == 0) len = buffer.Length – start;
650             int length = start + len;
651             if (length > buffer.Length) return null;
652             ushort crc = 0;// Initial value
653             for (int i = start; i < length; i++)
654             {
655                 crc ^= (ushort)(buffer[i] << 8);
656                 for (int j = 0; j < 8; j++)
657                 {
658                     if ((crc & 0x8000) > 0)
659                         crc = (ushort)((crc << 1) ^ 0x1021);
660                     else
661                         crc = (ushort)(crc << 1);
662                 }
663             }
664             byte[] ret = BitConverter.GetBytes(crc);
665             Array.Reverse(ret);
666             return ret;
667         }
668     /// **********************************************************************
669     /// Name: CRC32    x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
670     /// Poly: 0x04C11DB7
671     /// Init: 0xFFFFFFFF
672     /// Refin: true
673     /// Refout: true
674     /// Xorout: 0xFFFFFFFF
675     ///*************************************************************************
676         public static byte[] Crc22(byte[] buffer, int start = 0, int len = 0)
677         {
678             if (buffer == null || buffer.Length == 0) return null;
679             if (start < 0) return null;
680             if (len == 0) len = buffer.Length – start;
681             int length = start + len;
682             if (length > buffer.Length) return null;
683             uint crc = 0xFFFFFFFF;// Initial value
684             for (int i = start; i < length; i++)
685             {
686                 crc ^= buffer[i];
687                 for (int j = 0; j < 8; j++)
688                 {
689                     if ((crc & 1) > 0)
690                         crc = (crc >> 1) ^ 0xEDB88320;// 0xEDB88320= reverse 0x04C11DB7
691                     else
692                         crc = crc >> 1;
693                 }
694             }
695             byte[] ret = BitConverter.GetBytes(~crc);
696             Array.Reverse(ret);
697             return ret;
698         }
699     /// **********************************************************************
700     /// Name: CRC32/MPEG-2    x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
701     /// Poly: 0x04C11DB7
702     /// Init: 0xFFFFFFFF
703     /// Refin: false
704     /// Refout: false
705     /// Xorout: 0x00000000
706     ///*************************************************************************
707         public static byte[] Crc23(byte[] buffer, int start = 0, int len = 0)
708         {
709             if (buffer == null || buffer.Length == 0) return null;
710             if (start < 0) return null;
711             if (len == 0) len = buffer.Length – start;
712             int length = start + len;
713             if (length > buffer.Length) return null;
714             uint crc = 0xFFFFFFFF;// Initial value
715             for (int i = start; i < length; i++)
716             {
717                 crc ^= (uint)(buffer[i] << 24);
718                 for (int j = 0; j < 8; j++)
719                 {
720                     if ((crc & 0x80000000) > 0)
721                         crc = (crc << 1) ^ 0x04C11DB7;
722                     else
723                         crc = crc << 1;
724                 }
725             }
726             byte[] ret = BitConverter.GetBytes(crc);
727             Array.Reverse(ret);
728             return ret;
729         }

纵向冗余校验(Longitudinal Redundancy Check,简称:LRC)是通信中常用的一种校验形式,也称LRC校验或纵向校验。 它是一种从纵向通道上的特定比特串产生校验比特的错误检测方法。在行列格式中(如磁带),LRC经常是与VRC一起使用,这样就会为每个字符校验码。在工业领域Modbus协议Ascii模式采用该算法。 LRC计算校验码,具体算法如下:
/// 1、对需要校验的数据(2n个字符)两两组成一个16进制的数值求和。
/// 2、将求和结果与256求模。
/// 3、用256减去所得模值得到校验结果(另一种方法:将模值按位取反然后加1)。

1 public static byte[] Lrc(byte[] buffer, int start = 0, int len = 0)
2         {
3             if (buffer == null || buffer.Length == 0) return null;
4             if (start < 0) return null;
5             if (len == 0) len = buffer.Length – start;
6             int length = start + len;
7             if (length > buffer.Length) return null;
8             byte lrc = 0;// Initial value
9             for (int i = start; i < len; i++)
10             {
11                 lrc += buffer[i];
12             }
13             lrc = (byte)((lrc ^ 0xFF) + 1);
14             return new byte[] { lrc };
15         }

BCC(Block Check Character/信息组校验码),因校验码是将所有数据异或得出,故俗称异或校验。具体算法是:将每一个字节的数据(一般是两个16进制的字符)进行异或后即得到校验码。

public static byte[] Bcc(byte[] buffer, int start = 0, int len = 0)
{
if (buffer == null || buffer.Length == 0) return null;
if (start < 0) return null;
if (len == 0) len = buffer.Length – start;
int length = start + len;
if (length > buffer.Length) return null;
byte bcc = 0;// Initial value
for (int i = start; i < len; i++)
{
bcc ^= buffer[i];
}
return new byte[] { bcc };
}

检验和(checksum),在数据处理和数据通信领域中,用于校验目的地一组数据项的和。它通常是以十六进制为数制表示的形式。如果校验和的数值超过十六进制的FF,也就是255. 就要求其补码作为校验和。通常用来在通信中,尤其是远距离通信中保证数据的完整性和准确性。

1  public static byte[] allAdd(byte[] buffer, int start = 0, int len = 0)
2         {
3             if (buffer == null || buffer.Length == 0) return null;
4             if (start < 0) return null;
5             if (len == 0) len = buffer.Length – start;
6             int length = start + len;
7             if (length > buffer.Length) return null;
8             byte bcc = 0;// Initial value
9             for (int i = start; i < len; i++)
10             {
11                 bcc ^= buffer[i];
12             }
13             return new byte[] { bcc };
14         }

 

本文出自:从网上收集的方法,没有具体Url

Delphi 局域网点对点文件传输(IdTcpClient控件)

Delphi <wbr>局域网点对点文件传输(IdTcpClient控件)

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, ScktComp, IdTCPServer,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient;

type
TForm1 = class(TForm)
   Panel1: TPanel;
   Panel2: TPanel;
   SpeedButton1: TSpeedButton;
   SpeedButton2: TSpeedButton;
   SpeedButton3: TSpeedButton;
   LBFiles: TLabel;
   SpeedButton4: TSpeedButton;
   SpeedButton5: TSpeedButton;
   OpenDialog1: TOpenDialog;
   SaveDialog1: TSaveDialog;
   PB2: TProgressBar;
   PB1: TProgressBar;
   ListBox1: TListBox;
   Label2: TLabel;
   IdTCPClient1: TIdTCPClient;
   IdTCPServer1: TIdTCPServer;
   LBSend: TLabel;
   Edit1: TEdit;
   Label1: TLabel;
   IdTCPClient2: TIdTCPClient;
   IdTCPServer2: TIdTCPServer;
   procedure SpeedButton1Click(Sender: TObject);
   procedure ListBox1DblClick(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure SpeedButton2Click(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure SpeedButton4Click(Sender: TObject);
   procedure IdTCPServer1Execute(AThread: TIdPeerThread);
   procedure SpeedButton5Click(Sender: TObject);
   procedure SpeedButton3Click(Sender: TObject);
   procedure IdTCPServer2Connect(AThread: TIdPeerThread);
   procedure IdTCPServer2Execute(AThread: TIdPeerThread);
private
   { Private declarations }
public
   Function Act_DownFiles(CurFilePath,SerFilePath,CurFileName,SerFileName:String):Boolean;
end;

var
Form1: TForm1;
UserName:String;
RecivList:TStrings;
SendIP:String;
DownFlag:Boolean;
implementation

{$R *.dfm}

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
   if ListBox1.Items.IndexOf(OpenDialog1.FileName) = -1 then
   begin
     ListBox1.Items.Add(OpenDialog1.FileName);
   end;
end;

end;

procedure TForm1.ListBox1DblClick(Sender: TObject);
begin
if ListBox1.ItemIndex >=0 then
   ListBox1.Items.Delete(ListBox1.ItemIndex);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
self.Height:=267;
IdTCPServer2.Active:=True;
IdTCPServer1.Active:=True;
UserName:=’admin’;
RecivList:=TStringList.Create;
DownFlag:=True;
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
var
TemFiles:String;
begin

if ListBox1.Count > 0 then
begin
   SpeedButton2.Enabled:=False;
  
   TemFiles:=ListBox1.Items.CommaText;

   IdTCPClient2.Host :=Trim(Edit1.Text);//服务器的地址

   if  IdTCPClient2.Connected then
     IdTCPClient2.Disconnect;

   Try
     IdTCPClient2.Connect;
   except
     MessageBox(Handle,’服务器没有开启’,’提示’,MB_OK);
     Exit;
   end;

   with   IdTCPClient2   do
   begin
     while   Connected   do
     begin
       try
         WriteLn(‘SendFiles#’+ListBox1.Items.CommaText+’%’+UserName); //指定路径
       finally
         Disconnect;//断开连接
       end;
     end;
   end;

end
else
begin
   MessageBox(Handle,’请选择要传送的文件’,’提示’,MB_OK);
end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
RecivList.Free;
end;

procedure TForm1.SpeedButton4Click(Sender: TObject);
var
CurFilePath,SerFilePath:String;
FileName,TemStr:String;
i,TemInt:integer;
begin
SpeedButton4.Enabled:=False;

DownFlag:=True;
TemStr:=”;
TemInt:=0;

if SaveDialog1.Execute then
begin
   CurFilePath:=ExtractFilePath(SaveDialog1.FileName);

   for i:=0 to RecivList.Count – 1 do
   begin
     SerFilePath:=ExtractFilePath(RecivList.Strings[i]);
     FileName:=ExtractFileName(RecivList.Strings[i]);

     if not Act_DownFiles(CurFilePath,SerFilePath,FileName,FileName) then
     begin
       TemInt:=TemInt+1;
       TemStr:=TemStr+ FileName;
     end;
   end;

   if TemInt > 0 then
   begin
     MessageBox(Handle,PChar(TemStr+’文件没有传输成功’),’提示’,MB_OK);
   end
   else
   begin
     MessageBox(Handle,’所有文件传输成功’,’提示’,MB_OK);
   end;

   IdTCPClient1.Host :=SendIP;
  
   if  IdTCPClient1.Connected then
     IdTCPClient1.Disconnect;

   Try
     IdTCPClient1.Connect;
   except
     MessageBox(Handle,’服务器没有开启’,’提示’,MB_OK);
     Exit;
   end;

   with   IdTCPClient1   do
   begin
     while   Connected   do
     begin
       try
         WriteLn(‘OK’); //指定路径
       finally
         Disconnect;//断开连接
       end;
     end;
   end;

   Close;
end;
end;

Function TForm1.Act_DownFiles(CurFilePath,SerFilePath,CurFileName,SerFileName:String):Boolean;
var
TemFileName:String;
rbyte:array[0..4096] of byte;
sFile:TFileStream;
iFileSize:integer;
begin
PB1.Position:=0;
IdTCPClient1.Host :=SendIP;//服务器的地址

if  IdTCPClient1.Connected then
   IdTCPClient1.Disconnect;

Try
   IdTCPClient1.Connect;
except
   MessageBox(Handle,’服务器没有开启’,’提示’,MB_OK);
   Result:=False;
   Exit;
end;

with   IdTCPClient1   do
begin
   while   Connected   do
   begin
     try
       TemFileName:=SerFilePath+SerFileName;
       WriteLn(TemFileName); //指定路径

       if ReadLn<>’文件不存在’ then
       begin
         iFileSize:=IdTCPClient1.ReadInteger;
         PB1.Max :=  iFileSize div 100 ;
         sFile:=TFileStream.Create(CurFilePath+CurFileName,fmCreate);

         While iFileSize>4096 do
         begin
           if DownFlag then
           begin
             IdTCPClient1.ReadBuffer(rbyte,4096);// .ReadBuffer(rbyte,iLen);
             sFile.Write(rByte,4096);
             inc(iFileSize,-4096);
             PB1.Position:= PB1.Position +(4096 div 100) ;

             Application.ProcessMessages;
           end
           else
           begin
             Result:=False;
             Exit;
           end;
         end;

         IdTCPClient1.ReadBuffer(rbyte,iFileSize);// .ReadBuffer(rbyte,iLen);

         sFile.Write(rByte,iFileSize);
         sFile.Free;

         PB1.Position:=PB1.Max;
       end;

     finally
       Disconnect;//断开连接
     end;
   end;
end;
Result:=True;
end;

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
RecevFileName:string;
iFileHandle:integer;
iFileLen,cnt:integer;
buf:array[0..4096] of byte;
begin
if not AThread.Terminated and AThread.Connection.Connected then  //注意这里
begin
   with   AThread.Connection   do
   begin
     Try
       RecevFileName:=AThread.Connection.ReadLn;

       if RecevFileName=’OK’ then
       begin
         PB2.Position:=0;
         LBSend.Caption:=’All Files Send OK’;
       end;

       if RecevFileName=’RefusedAll’ then
       begin
         LBSend.Caption:=’All Files are Refused’;
         PB2.Position:=0;
       end;

       if (RecevFileName<>’OK’) and (RecevFileName<>’RefusedAll’) then
       begin
         if FileExists(RecevFileName) then
         begin
           PB2.Position:=0;

           WriteLn(RecevFileName);

           LBSend.Caption:=’Send: ‘+RecevFileName;

           iFileHandle:=FileOpen(RecevFileName,fmOpenRead); //得到此文件大小
           iFileLen:=FileSeek(iFileHandle,0,2);

           FileSeek(iFileHandle,0,0);
           AThread.Connection.WriteInteger(iFileLen,True);////hjh 20071009

           PB2.Max :=  iFileLen div 100 ;
        
           while iFileLen >0 do
           begin
             cnt:=FileRead(iFileHandle,buf,4096);
             AThread.Connection.WriteBuffer(buf,cnt,True);/////hjh20071009
             iFileLen:=iFileLen-cnt;
             PB2.Position:=PB2.Position +(4096 div 100) ;
             Application.ProcessMessages;
           end;

           FileClose(iFileHandle);
         end
         else
         begin
           WriteLn(‘文件不存在’);
         end;
       end;
     Finally
       Disconnect;//断开连接
     end;
   end;
end;
end;

procedure TForm1.SpeedButton5Click(Sender: TObject);
var
i:integer;
begin
DownFlag:=False;

IdTCPClient1.Host :=SendIP;//服务器的地址

if  IdTCPClient1.Connected then
   IdTCPClient1.Disconnect;

Try
   IdTCPClient1.Connect;
except
   MessageBox(Handle,’服务器没有开启’,’提示’,MB_OK);
   Exit;
end;

with   IdTCPClient1   do
begin
   while   Connected   do
   begin
     try

       WriteLn(‘RefusedAll’); //指定路径

     finally
       Disconnect;//断开连接
     end;
   end;
end;

IdTCpClient1.Disconnect;

//Application.Terminate;
end;

procedure TForm1.SpeedButton3Click(Sender: TObject);
var
TemStr:String;
begin
if Trim(LBSend.Caption)=” then
begin
   Close;
end;

if Trim(LBSend.Caption)=’All Files Send OK’ then
begin
   Close;
end
else
begin
   PB2.Position:=0;

   IdTCPClient2.Host :=Trim(Edit1.Text);//服务器的地址

   if  IdTCPClient2.Connected then
     IdTCPClient2.Disconnect;

   Try
     IdTCPClient2.Connect;
   except
     MessageBox(Handle,’服务器没有开启’,’提示’,MB_OK);
     Exit;
   end;

   with   IdTCPClient2   do
   begin
     while   Connected   do
     begin
       try
         WriteLn(‘RefuseSend’); //指定路径

       finally
         Disconnect;//断开连接
       end;
     end;
   end;
  
end;

end;

procedure TForm1.IdTCPServer2Connect(AThread: TIdPeerThread);
begin
SendIP:=AThread.Connection.Socket.Binding.PeerIP;

end;

procedure TForm1.IdTCPServer2Execute(AThread: TIdPeerThread);
var
RecivStr,FileStr:String;
TemList:TStrings;
TemUser:String;
i:integer;
begin
if not AThread.Terminated and AThread.Connection.Connected then  //注意这里
begin
   with   AThread.Connection   do
   begin
     Try

       FileStr:=”;
       RecivStr:=ReadLn;

       if RecivStr <>’RefuseSend’ then
       begin
         if Pos(‘SendFiles’,RecivStr) > 0 then
         begin
           Self.Height:=130;
           Panel1.Visible:=False;
           RecivList.Clear;

           RecivList.CommaText:=Copy(RecivStr,Pos(‘#’,RecivStr)+1,Pos(‘%’,RecivStr)-Pos(‘#’,RecivStr)-1);
           TemUser:=Copy(RecivStr,Pos(‘%’,RecivStr)+1,Length(RecivStr)-Pos(‘%’,RecivStr));

           for i:=0 to RecivList.Count -1 do
           begin
             FileStr:=FileStr+ExtractFileName(RecivList.Strings[i])+’,’;
           end;

           LBFiles.Caption:=TemUser+’ 向您发送文件:’+FileStr+’请接收’;
         end;
       end;

       if RecivStr=’RefuseSend’ then
       begin
         LBFiles.Caption:=’对方取消了发送文件’;
         PB1.Position:=0;
         DownFlag:=False;
       end;

     Finally
       Disconnect;
     end;
   end;
end;

end;

end.

本文出自:http://blog.sina.com.cn/s/blog_4a8552f80100azew.html