--- /dev/null
+//-----------------------------------------------------------------------------\r
+// Routines to compute the CRCs (two different flavours, just for confusion)\r
+// required for ISO 14443, swiped directly from the spec.\r
+//-----------------------------------------------------------------------------\r
+\r
+#define CRC_14443_A 0x6363 /* ITU-V.41 */\r
+#define CRC_14443_B 0xFFFF /* ISO/IEC 13239 (formerly ISO/IEC 3309) */\r
+\r
+static unsigned short UpdateCrc14443(unsigned char ch, unsigned short *lpwCrc)\r
+{\r
+ ch = (ch ^ (unsigned char) ((*lpwCrc) & 0x00FF));\r
+ ch = (ch ^ (ch << 4));\r
+ *lpwCrc = (*lpwCrc >> 8) ^ ((unsigned short) ch << 8) ^\r
+ ((unsigned short) ch << 3) ^ ((unsigned short) ch >> 4);\r
+ return (*lpwCrc);\r
+}\r
+\r
+static void ComputeCrc14443(int CrcType, BYTE *Data, int Length,\r
+ BYTE *TransmitFirst, BYTE *TransmitSecond)\r
+{\r
+ unsigned char chBlock;\r
+ unsigned short wCrc=CrcType;\r
+\r
+ do {\r
+ chBlock = *Data++;\r
+ UpdateCrc14443(chBlock, &wCrc);\r
+ } while (--Length);\r
+\r
+ if (CrcType == CRC_14443_B)\r
+ wCrc = ~wCrc; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */\r
+\r
+ *TransmitFirst = (BYTE) (wCrc & 0xFF);\r
+ *TransmitSecond = (BYTE) ((wCrc >> 8) & 0xFF);\r
+ return;\r
+}\r