CRC-16 in Swift 3.x+
I have been trying to do this for sometime. Inspired by a LabVIEW implementation at a previous job, I have been trying to implement the same CRC-16 algorithm in Swift. TheĀ cyclic redundancy check is a mathematical computation used in various areas of hardware and software to detect false bits in a stream of data. Computing CRCs can be tricky and there are so many ways to compute a CRC. The implementation shared here can compute two types of CRC-16s depending on the specification, either ARC or MODBUS. In both cases, the polynomial used is the bit-reverse of the 0x8005 polynomial show here:
which is 0xA001. The initial accumulator value is set depending on the kind of CRC specified, zero for ARC and 0xFFFF for MODBUS. I used this site and this one for outside verification.
import Foundation enum CRCType { case MODBUS case ARC } func crc16(_ data: [UInt8], type: CRCType) -> UInt16? { if data.isEmpty { return nil } let polynomial: UInt16 = 0xA001 // A001 is the bit reverse of 8005 var accumulator: UInt16 // set the accumulator initial value based on CRC type if type == .ARC { accumulator = 0 } else { // default to MODBUS accumulator = 0xFFFF } // main computation loop for byte in data { var tempByte = UInt16(byte) for _ in 0 ..< 8 { let temp1 = accumulator & 0x0001 accumulator = accumulator >> 1 let temp2 = tempByte & 0x0001 tempByte = tempByte >> 1 if (temp1 ^ temp2) == 1 { accumulator = accumulator ^ polynomial } } } return accumulator } // try it out... let data = [UInt8]([0x31, 0x32, 0x33]) let arcValue = crc16(data, type: .ARC) let modbusValue = crc16(data, type: .MODBUS) if arcValue != nil && modbusValue != nil { let arcStr = String(format: "0x%4X", arcValue!) let modbusStr = String(format: "0x%4X", modbusValue!) print("CRCs: ARC = " + arcStr + " MODBUS = " + modbusStr) }
Here is the output in Xcode:

Compare the result to the previously mentioned online CRC sites:


Given more time, this can be improved and expanded to do more CRC-16 computation types.