使用6位块的更好方法

时间:2015-09-22 13:14:02

标签: swift functional-programming swift2

这是一种更优雅的方式吗?

我想知道是否有某种方法可以使用swift的功能编程方面将数组块化为 6位块

我有什么作品,但它并不像其最好的做事方式

伪代码

我认为有4种类型的掩蔽可能

[1111 1122]  [2222 3333]  [3344 4444]
  • 前6位
  • 最后2位和下一个字节的前4位
  • 最后4位和下一个字节的前2位
  • 最后6位

我把一些基本上遍历字节的代码放在一起,计算出" type"掩饰我们正在做 - 并适当掩盖。它只是感觉有点粗糙 - 也许有一种方法可以使用一些功能命令,如map来将字节结构分解为 6位块

步骤1 - 转换为字节数组

我做的第一件事就是把我的NSData分成UInt8

数组。
let ptr = UnsafeMutablePointer<UInt8>(rawNSData.bytes)
let bytes = UnsafeMutableBufferPointer<UInt8>(start: ptr, count: rawNSData.length)

第2步 -

接下来我编写了这个解析器,它基本上跟踪了什么&#34; byte&#34;我们在哪,&#34;键入&#34;掩蔽我们需要执行(见上文)。

func parseDLAC(data : NSData, startingByte startingDataLocation : Int) -> String {

    var ret = "";

    ///Tracks the current "decoding" - so that we can figure out which type of masking to do
    var currentDLACNumber = 0

    while (true) {

        // 4 types of masking possible
        let maskIteration = currentDLACNumber % 4

        ///Where to start the current decoding
        let startingByte = (currentDLACNumber * 6) / 8 + startingDataLocation
        let endingByte   = ((currentDLACNumber + 1 ) * 6) / 8 + startingDataLocation

        if (endingByte > data.length) {
            return "ERROR";
        }

        var rawValue : UInt8

        switch(maskIteration) {

        case 0:  // grab 1st 6 bits and shift right
            rawValue = (bytes[startingByte] & 0xFC) >> 2
        case 1:  // 2 & 4
            rawValue = ((bytes[startingByte] & 0x03) << 4) | ((bytes[startingByte+1] & 0xF0) >> 4)
        case 2:
            rawValue = ((bytes[startingByte] & 0x0F ) << 2) | ((bytes[startingByte+1] & 0xC0) >> 6)
        case 3:
            rawValue = (bytes[startingByte] & 0x3F)
        default:
            rawValue = 0
        }

        if (rawValue == 0) {
            return ret
        }

        ret += decodeDLAC(rawValue);


        // Next!
        currentDLACNumber++
    }
    return ret;
}

解决方案

我很想知道是否有更优雅的方式来重写这段代码。

给定NSData和起始地址(字节偏移)有一种方法可以创建一个6位块的数组(UInt8&#39; s)。我对map感到困惑,因为我知道&#34;尝试&#34;使用不同的数组元素。我也不知道是否有UnsafeMutalbeBitPointer类型可能有帮助。

感谢您的帮助 - 是的 - 不可能是一个有效的答案。

1 个答案:

答案 0 :(得分:1)

使用该语言的功能元素并不容易,但通过一次处理三个字节的数据,可以大大简化事情。这样,您就可以对四个掩码的应用程序进行硬编码,并完全避免使用switch语句。

首先,确保[bytes]中的字节数可以被3整除。您可以通过从原始数据中提取字节后用一个或两个零“填充”数组来完成此操作。

之后你可以这样做:

for var i = startingDataLocation  ; i+2 < bytes.length ; i += 3 {
    ret += decodeDLAC((bytes[i] & 0xFC) >> 2)
    ret += decodeDLAC(((bytes[i] & 0x03) << 4) | ((bytes[i+1] & 0xF0) >> 4))
    ret += decodeDLAC(((bytes[i+1] & 0x0F ) << 2) | ((bytes[i+2] & 0xC0) >> 6))
    ret += decodeDLAC((bytes[i+2] & 0x3F))
}

P.S。此解决方案基于Dijkstra的故事"A Parable"