Swift - Convert UInt8 byte to array of bits

六眼飞鱼酱① 提交于 2019-12-06 08:16:22

Here's a basic function to get a Bit array from a byte:

func bits(fromByte byte: UInt8) -> [Bit] {
    var byte = byte
    var bits = [Bit](repeating: .zero, count: 8)
    for i in 0..<8 {
        let currentBit = byte & 0x01
        if currentBit != 0 {
            bits[i] = .one
        }

        byte >>= 1
    }

    return bits
}

Here, Bit is a custom enum type that I have defined as follows:

enum Bit: UInt8, CustomStringConvertible {
    case zero, one

    var description: String {
        switch self {
        case .one:
            return "1"
        case .zero:
            return "0"
        }
    }
}

With this setup, the output of the following code:

let byte: UInt8 = 0x1f

print(bits(fromByte: byte))

would be:

[1, 1, 1, 1, 1, 0, 0, 0]

Improving on mohak's answer. With a generic function or an extension to cater for more than just UInt8.

enum Bit: UInt8, CustomStringConvertible {
    case zero, one

    var description: String {
        switch self {
        case .one:
            return "1"
        case .zero:
            return "0"
        }
    }
}

func bits<T: FixedWidthInteger>(fromBytes bytes: T) -> [Bit] {
    // Make variable
    var bytes = bytes
    // Fill an array of bits with zeros to the fixed width integer length
    var bits = [Bit](repeating: .zero, count: T.bitWidth)
    // Run through each bit (LSB first)
    for i in 0..<T.bitWidth {
        let currentBit = bytes & 0x01
        if currentBit != 0 {
            bits[i] = .one
        }

        bytes >>= 1
    }

    return bits
}

extension FixedWidthInteger {
    var bits: [Bit] {
        // Make variable
        var bytes = self
        // Fill an array of bits with zeros to the fixed width integer length
        var bits = [Bit](repeating: .zero, count: self.bitWidth)
        // Run through each bit (LSB first)
        for i in 0..<self.bitWidth {
            let currentBit = bytes & 0x01
            if currentBit != 0 {
                bits[i] = .one
            }

            bytes >>= 1
        }

        return bits
    }
}

You can do some bitwise operations to get the value of the bits at indices 1-4.

// An example byte
let a: UInt8 = 0b00011010

// Extract the bits (using 0b01111000 as a bitmask) 
// in indices 1 to 4, then shift right by 3 places
// to remove indices 5 to 7
var b = (a & 0b01111000) >> 3 

// In this case, b is now 3 (or 11 in binary)
print(b)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!