Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift crc-16 cccitt问题-计算不正确_Swift_Crc16 - Fatal编程技术网

Swift crc-16 cccitt问题-计算不正确

Swift crc-16 cccitt问题-计算不正确,swift,crc16,Swift,Crc16,试图在我的蓝牙ios移动应用程序中实现此CRC16 CITT校验和: extension Data { typealias bit_order_16 = (_ value: UInt16) -> UInt16 typealias bit_order_8 = (_ value: UInt8) -> UInt8 func crc16Check() -> UInt16 { let data = self as! NSData let bytes = UnsafePoi

试图在我的蓝牙ios移动应用程序中实现此CRC16 CITT校验和:

extension Data {

typealias bit_order_16 = (_ value: UInt16) -> UInt16
typealias bit_order_8 = (_ value: UInt8) -> UInt8


func crc16Check() -> UInt16 {
 let data = self as! NSData
    let bytes = UnsafePointer<UInt8>(data.bytes.assumingMemoryBound(to: UInt8.self))
    let length = data.length
    return crc16ccitt(message: bytes, nBytes: length)
}


func straight_16(value: UInt16) -> UInt16 {
    return value
}

func reverse_16(value: UInt16) -> UInt16 {
    var value = value
    var reversed: UInt16 = 0
    for i in stride(from: 0, to: 16, by: 1) {
        reversed <<= 1
        reversed |= (value & 0x1)
        value >>= 1
    }
    return reversed
}

func straight_8(value: UInt8) -> UInt8 {
    return value
}

func reverse_8(value: UInt8) -> UInt8 {
    var value = value
    var reversed: UInt8 = 0
    for i in stride(from: 0, to: 8, by: 1) {
        reversed <<= 1
        reversed |= (value & 0x1)
        value >>= 1
    }
    return reversed
}


func crc16(message: UnsafePointer<UInt8>, nBytes: Int, data_order: bit_order_8, remainder_order: bit_order_16, remainder: UInt16, polynomial: UInt16) -> UInt16 {
    var remainder = remainder

    for byte in stride(from: 0, to: nBytes, by: 1) {

        remainder ^= UInt16(data_order(message[byte]) << 8)
        var bit = 8
        while bit > 0 {
            if (remainder & 0x8000) != 0 {
                remainder = (remainder << 1) ^ 0x1021
            } else {
                remainder = (remainder << 1)
            }
            bit -= 1
        }
    }

    return remainder_order(remainder)
}


func crc16ccitt(message: UnsafePointer<UInt8>, nBytes: Int) -> UInt16 {

    return crc16(message: message, nBytes: nBytes, data_order: straight_8, remainder_order: straight_16, remainder: 0xffff, polynomial: 0x1021)

}

func crc16ccitt_xmodem(message: UnsafeMutablePointer<UInt8>, nBytes: Int) -> UInt16 {
    return crc16(message: message, nBytes: nBytes, data_order: straight_8, remainder_order: straight_16, remainder: 0x0000, polynomial: 0x1021)
}

func crc16ccitt_kermit(message: UnsafeMutablePointer<UInt8>, nBytes: Int) -> UInt16 {
    let swap = crc16(message: message, nBytes: nBytes, data_order: reverse_8, remainder_order: reverse_16, remainder: 0x0000, polynomial: 0x1021)
    return swap << 8 | swap >> 8
}

func crc16ccitt_1d0f(message: UnsafeMutablePointer<UInt8>, nBytes: Int) -> UInt16 {
    return crc16(message: message, nBytes: nBytes, data_order: straight_8, remainder_order: straight_16, remainder: 0x1d0f, polynomial: 0x1021)
}

func crc16ibm(message: UnsafeMutablePointer<UInt8>, nBytes: Int) -> UInt16 {
    return crc16(message: message, nBytes: nBytes, data_order: reverse_8, remainder_order: reverse_16, remainder: 0x0000, polynomial: 0x8005)
}
//打印出CC9C

CC9C不正确

答案应该是:716D


似乎无法在crc16 ccitt计算中找到错误。有人能帮我找出问题所在吗,因为我真的不确定哪里出了问题。我花了太长时间想弄明白。感谢社区随时提供帮助。谢谢。

这里的错误是操作顺序错误:

remainder ^= UInt16(data_order(message[byte]) << 8)
因此,在将数字向左移动之前,该数字将转换为16位值

这个问题可能不会出现在类似的C程序中,在该程序中,所有整数操作数在进行计算之前都会提升为int–此类隐式类型转换不会在Swift中完成

另一个错误是func crc16使用固定多项式0x1021而不是多项式参数。这会导致crc16ibm校验和的结果错误

还请注意,不需要在crc16Check中转换为NSData。这种方法可以简化为

func crc16Check() -> UInt16 {
    return self.withUnsafeBytes { [length = self.count] in
        crc16ccitt(message: $0, nBytes: length)
    }
}
更好的方法是:在self上使用all methods运算符,而不是传递不可分配的指针和长度:

extension Data {
    
    typealias bit_order_16 = (_ value: UInt16) -> UInt16
    typealias bit_order_8 = (_ value: UInt8) -> UInt8
    
    func straight_16(value: UInt16) -> UInt16 {
        return value
    }
    
    func reverse_16(value: UInt16) -> UInt16 {
        var value = value
        var reversed: UInt16 = 0
        for _ in 0..<16 {
            reversed <<= 1
            reversed |= (value & 0x1)
            value >>= 1
        }
        return reversed
    }
    
    func straight_8(value: UInt8) -> UInt8 {
        return value
    }
    
    func reverse_8(value: UInt8) -> UInt8 {
        var value = value
        var reversed: UInt8 = 0
        for _ in 0..<8 {
            reversed <<= 1
            reversed |= (value & 0x1)
            value >>= 1
        }
        return reversed
    }
    
    func crc16(data_order: bit_order_8, remainder_order: bit_order_16, remainder: UInt16, polynomial: UInt16) -> UInt16 {
        var remainder = remainder
        
        for byte in self {
            remainder ^= UInt16(data_order(byte)) << 8
            for _ in 0..<8 {
                if (remainder & 0x8000) != 0 {
                    remainder = (remainder << 1) ^ polynomial
                } else {
                    remainder = (remainder << 1)
                }
            }
        }
        return remainder_order(remainder)
    }
    
    func crc16ccitt() -> UInt16 {
        return crc16(data_order: straight_8, remainder_order: straight_16, remainder: 0xffff, polynomial: 0x1021)
    }
    
    func crc16ccitt_xmodem() -> UInt16 {
        return crc16(data_order: straight_8, remainder_order: straight_16, remainder: 0x0000, polynomial: 0x1021)
    }
    
    func crc16ccitt_kermit() -> UInt16 {
        let swap = crc16(data_order: reverse_8, remainder_order: reverse_16, remainder: 0x0000, polynomial: 0x1021)
        return swap.byteSwapped
    }
    
    func crc16ccitt_1d0f() -> UInt16 {
        return crc16(data_order: straight_8, remainder_order: straight_16, remainder: 0x1d0f, polynomial: 0x1021)
    }
    
    func crc16ibm() -> UInt16 {
        return crc16(data_order: reverse_8, remainder_order: reverse_16, remainder: 0x0000, polynomial: 0x8005)
    }
}

这些数字与此结果一致。

错误在于此处的操作顺序错误:

remainder ^= UInt16(data_order(message[byte]) << 8)
因此,在将数字向左移动之前,该数字将转换为16位值

这个问题可能不会出现在类似的C程序中,在该程序中,所有整数操作数在进行计算之前都会提升为int–此类隐式类型转换不会在Swift中完成

另一个错误是func crc16使用固定多项式0x1021而不是多项式参数。这会导致crc16ibm校验和的结果错误

还请注意,不需要在crc16Check中转换为NSData。这种方法可以简化为

func crc16Check() -> UInt16 {
    return self.withUnsafeBytes { [length = self.count] in
        crc16ccitt(message: $0, nBytes: length)
    }
}
更好的方法是:在self上使用all methods运算符,而不是传递不可分配的指针和长度:

extension Data {
    
    typealias bit_order_16 = (_ value: UInt16) -> UInt16
    typealias bit_order_8 = (_ value: UInt8) -> UInt8
    
    func straight_16(value: UInt16) -> UInt16 {
        return value
    }
    
    func reverse_16(value: UInt16) -> UInt16 {
        var value = value
        var reversed: UInt16 = 0
        for _ in 0..<16 {
            reversed <<= 1
            reversed |= (value & 0x1)
            value >>= 1
        }
        return reversed
    }
    
    func straight_8(value: UInt8) -> UInt8 {
        return value
    }
    
    func reverse_8(value: UInt8) -> UInt8 {
        var value = value
        var reversed: UInt8 = 0
        for _ in 0..<8 {
            reversed <<= 1
            reversed |= (value & 0x1)
            value >>= 1
        }
        return reversed
    }
    
    func crc16(data_order: bit_order_8, remainder_order: bit_order_16, remainder: UInt16, polynomial: UInt16) -> UInt16 {
        var remainder = remainder
        
        for byte in self {
            remainder ^= UInt16(data_order(byte)) << 8
            for _ in 0..<8 {
                if (remainder & 0x8000) != 0 {
                    remainder = (remainder << 1) ^ polynomial
                } else {
                    remainder = (remainder << 1)
                }
            }
        }
        return remainder_order(remainder)
    }
    
    func crc16ccitt() -> UInt16 {
        return crc16(data_order: straight_8, remainder_order: straight_16, remainder: 0xffff, polynomial: 0x1021)
    }
    
    func crc16ccitt_xmodem() -> UInt16 {
        return crc16(data_order: straight_8, remainder_order: straight_16, remainder: 0x0000, polynomial: 0x1021)
    }
    
    func crc16ccitt_kermit() -> UInt16 {
        let swap = crc16(data_order: reverse_8, remainder_order: reverse_16, remainder: 0x0000, polynomial: 0x1021)
        return swap.byteSwapped
    }
    
    func crc16ccitt_1d0f() -> UInt16 {
        return crc16(data_order: straight_8, remainder_order: straight_16, remainder: 0x1d0f, polynomial: 0x1021)
    }
    
    func crc16ibm() -> UInt16 {
        return crc16(data_order: reverse_8, remainder_order: reverse_16, remainder: 0x0000, polynomial: 0x8005)
    }
}

这些数字与此结果一致。

@user11058774:注意,func crc16使用固定多项式0x1021而不是多项式参数。@user11058774:注意,func crc16使用固定多项式0x1021而不是多项式参数。