Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/98.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
Ios 解码某些Base64字符串时出错,但其他字符串除外_Ios_Swift_Base64_Bytearray - Fatal编程技术网

Ios 解码某些Base64字符串时出错,但其他字符串除外

Ios 解码某些Base64字符串时出错,但其他字符串除外,ios,swift,base64,bytearray,Ios,Swift,Base64,Bytearray,为了简单起见,我将只对单个字节进行编码/解码 如果我对字节127进行编码,我会得到base64字符串“fw==”,它可以成功解码回字节127。但是,如果我编码一个字节≥ 128,那么即使我可以生成一个没有错误的base64字符串(例如,字节128给出了字符串“gA==”),但当我尝试解码它时,我会得到一个错误 以下是我的代码,可以复制粘贴到任何Xcode游乐场,以重现问题: func stringToByteArray(string: String) -> [UInt8] { va

为了简单起见,我将只对单个字节进行编码/解码

如果我对字节127进行编码,我会得到base64字符串“fw==”,它可以成功解码回字节127。但是,如果我编码一个字节≥ 128,那么即使我可以生成一个没有错误的base64字符串(例如,字节128给出了字符串“gA==”),但当我尝试解码它时,我会得到一个错误

以下是我的代码,可以复制粘贴到任何Xcode游乐场,以重现问题:

func stringToByteArray(string: String) -> [UInt8] {
    var bytes: [UInt8] = [];
    for code in string.utf8 {
        bytes.append(UInt8(code));
    }
    return bytes;
}

func byteArrayToBase64(bytes: [UInt8]) -> String {
    let nsdata: NSData = NSData(bytes: bytes as [Byte], length: bytes.count)
    let base64Encoded: NSString = nsdata.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0));
    return String(base64Encoded);
}

func base64ToByteArray(base64String: String) -> [UInt8] {
    let nsdata: NSData = NSData(base64EncodedString: base64String, options: NSDataBase64DecodingOptions(rawValue: 0))!
    let base64Decoded: NSString = NSString(data: nsdata, encoding: NSUTF8StringEncoding)!
    return stringToByteArray(String(base64Decoded));
}

/* Replacing 127 with 128 below or greater produces an error */
var testString = byteArrayToBase64([127]);
base64ToByteArray(testString)
问题在于:

let base64Decoded: NSString = NSString(data: nsdata, encoding: NSUTF8StringEncoding)!
将解码后的数据转换为字符串。这对我来说是失败的
[128]
,因为这不代表有效的UTF-8序列

以下是一个避免使用中间字符串的版本:

func base64ToByteArray(base64String: String) -> [UInt8] {
    let nsdata: NSData = NSData(base64EncodedString: base64String, options: NSDataBase64DecodingOptions(rawValue: 0))!
    // Create array of the required size ...
    var bytes = [UInt8](count: nsdata.length, repeatedValue: 0)
    // ... and fill it with the data
    nsdata.getBytes(&bytes)
    return bytes
}
备注:

  • options:nsdatabase64解码选项(rawValue:0)
    可以简化 至
    选项:无
  • 代码中存在一些不必要的类型注释和转换
  • 如果
    baseString
    不是有效的Base64字符串,则函数将崩溃。 您可以将其更改为返回可选的
那么它看起来是这样的:

func byteArrayToBase64(bytes: [UInt8]) -> String {
    let nsdata = NSData(bytes: bytes, length: bytes.count)
    let base64Encoded = nsdata.base64EncodedStringWithOptions(nil);
    return base64Encoded;
}

func base64ToByteArray(base64String: String) -> [UInt8]? {
    if let nsdata = NSData(base64EncodedString: base64String, options: nil) {
        var bytes = [UInt8](count: nsdata.length, repeatedValue: 0)
        nsdata.getBytes(&bytes)
        return bytes
    }
    return nil // Invalid input
}
用法示例:

let testString = byteArrayToBase64([127, 128, 0, 130]);
println(testString) // Output: f4AAgg==
if let result = base64ToByteArray(testString) {
    println(result) // Output: [127, 128, 0, 130]
} else {
    println("failed")
}

更新Swift 2/Xcode 7:

func byteArrayToBase64(bytes: [UInt8]) -> String {
    let nsdata = NSData(bytes: bytes, length: bytes.count)
    let base64Encoded = nsdata.base64EncodedStringWithOptions([]);
    return base64Encoded;
}

func base64ToByteArray(base64String: String) -> [UInt8]? {
    if let nsdata = NSData(base64EncodedString: base64String, options: []) {
        var bytes = [UInt8](count: nsdata.length, repeatedValue: 0)
        nsdata.getBytes(&bytes, length: bytes.count)
        return bytes
    }
    return nil // Invalid input
}

let testString = byteArrayToBase64([127, 128, 0, 130]);
print(testString) // Output: f4AAgg==
if let result = base64ToByteArray(testString) {
    print(result) // Output: [127, 128, 0, 130]
} else {
    print("failed")
}
问题在于:

let base64Decoded: NSString = NSString(data: nsdata, encoding: NSUTF8StringEncoding)!
将解码后的数据转换为字符串。这对我来说是失败的
[128]
,因为这不代表有效的UTF-8序列

以下是一个避免使用中间字符串的版本:

func base64ToByteArray(base64String: String) -> [UInt8] {
    let nsdata: NSData = NSData(base64EncodedString: base64String, options: NSDataBase64DecodingOptions(rawValue: 0))!
    // Create array of the required size ...
    var bytes = [UInt8](count: nsdata.length, repeatedValue: 0)
    // ... and fill it with the data
    nsdata.getBytes(&bytes)
    return bytes
}
备注:

  • options:nsdatabase64解码选项(rawValue:0)
    可以简化 至
    选项:无
  • 代码中存在一些不必要的类型注释和转换
  • 如果
    baseString
    不是有效的Base64字符串,则函数将崩溃。 您可以将其更改为返回可选的
那么它看起来是这样的:

func byteArrayToBase64(bytes: [UInt8]) -> String {
    let nsdata = NSData(bytes: bytes, length: bytes.count)
    let base64Encoded = nsdata.base64EncodedStringWithOptions(nil);
    return base64Encoded;
}

func base64ToByteArray(base64String: String) -> [UInt8]? {
    if let nsdata = NSData(base64EncodedString: base64String, options: nil) {
        var bytes = [UInt8](count: nsdata.length, repeatedValue: 0)
        nsdata.getBytes(&bytes)
        return bytes
    }
    return nil // Invalid input
}
用法示例:

let testString = byteArrayToBase64([127, 128, 0, 130]);
println(testString) // Output: f4AAgg==
if let result = base64ToByteArray(testString) {
    println(result) // Output: [127, 128, 0, 130]
} else {
    println("failed")
}

更新Swift 2/Xcode 7:

func byteArrayToBase64(bytes: [UInt8]) -> String {
    let nsdata = NSData(bytes: bytes, length: bytes.count)
    let base64Encoded = nsdata.base64EncodedStringWithOptions([]);
    return base64Encoded;
}

func base64ToByteArray(base64String: String) -> [UInt8]? {
    if let nsdata = NSData(base64EncodedString: base64String, options: []) {
        var bytes = [UInt8](count: nsdata.length, repeatedValue: 0)
        nsdata.getBytes(&bytes, length: bytes.count)
        return bytes
    }
    return nil // Invalid input
}

let testString = byteArrayToBase64([127, 128, 0, 130]);
print(testString) // Output: f4AAgg==
if let result = base64ToByteArray(testString) {
    print(result) // Output: [127, 128, 0, 130]
} else {
    print("failed")
}