首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用位运算符将带有NSData字节的Obj-C方法转换为Swift

如何使用位运算符将带有NSData字节的Obj-C方法转换为Swift
EN

Stack Overflow用户
提问于 2018-06-02 02:18:09
回答 2查看 298关注 0票数 1

我正在尝试将Objective C方法转换为Swift,但为了做到这一点,我需要一些帮助来理解发生了什么。

对于上下文,此方法的输入以NSString开始,然后将其转换为使用utf8编码的NSData对象。然后将该数据对象的字节传递给该方法( message参数)。

然后,此方法的返回值通过writeData发送到某个CBPeripheral的某个特征。

这是我的理解(从Swift的角度)。

  • 传入的消息是一个UInt8字节数组:[UInt8]
  • 3变量被创建为CoreBluetooth值;然后将crcValbyteValUInt32设置为UInt32类型的最大值,然后循环传递的D21>字节数组中的每个字节,并执行某种操作以生成D22值的最终结果并将其附加到最终用于通过CoreBluetooth的D23命令发送到CoreBluetooth的writeData值的最终结果

我对按位运算符或者为什么下面的方法做它正在做的事情并不是很了解,因为没有文档。有没有人能帮我把这部分或全部清理清楚?我希望写一个与这个方法等价的Swift版本。谢谢。

代码语言:javascript
复制
- (uint32_t) computeCRC:(uint8_t *)message len:(NSUInteger)msgLen {

    uint32_t crcVal = 0, byteVal, mask;

    crcVal = 0xFFFFFFFF;
    for (int i=0; i<msgLen; i++) {
        byteVal = message[i];
        crcVal ^= byteVal;
        for (int j=7; j>=0; j--) {
            mask = -(crcVal&1);
            crcVal = (crcVal>>1)^(0xEDB88320 & mask);
        }
    }

    return ~crcVal;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-02 02:58:05

与其从头开始编写实现,为什么不使用crc32的zlib实现呢?

代码语言:javascript
复制
import zlib

func crc32(from data: Data) -> UInt {
    return data.withUnsafeBytes { (buffer: UnsafePointer<Bytef>) -> UInt in
       return zlib.crc32(0, buffer, uInt(data.count))
    }
}

但是,为了帮助您理解按位操作,请执行以下操作:

代码语言:javascript
复制
func computeCRC(message: [UInt8]) -> UInt32 {
    var crc: UInt32 = 0xFFFFFFFF

    for byte in message {
        crc ^= UInt32(byte)
        for _ in 0 ..< 8 {
            // negation using 2-complement: -x = ~x + 1
            // use &+ addition with overflow
            let mask = ~(crc & 1) &+ 1
            crc = (crc >> 1) ^ (0xEDB88320 & mask)
        }
    }

    return ~crc
}

请注意,我们不需要传递Swift中的字节数。这两个实现具有不同的签名,并返回略有不同的类型,但它们都给出相同的结果。

票数 4
EN

Stack Overflow用户

发布于 2018-06-02 20:51:20

对于计算CRC16,您可以使用

代码语言:javascript
复制
import Foundation

extension Data {

    enum CRCType {
        case MODBUS
        case ARC
    }

    static 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
    }
}

here

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50649035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档