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 external 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.