某些解码Base64编码字符串时错误,但不是别人 [英] Error when decoding certain Base64 strings, but not others

查看:1543
本文介绍了某些解码Base64编码字符串时错误,但不是别人的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要保持这个简单,我将只编码/单字节进行解码。

如果我带code中的字节127,我得到的base64字符串FW ==它可以成功地去codeD回字节127但是,如果我带codeA字节≥ 128,那么即使我能产生一个base64字符串没有错误(例如,字节128给人的字符串嘎==),我得到一个错误,当我尝试去code吧。

下面是我的code可以复制粘贴到某X code操场上重现该问题:

  FUNC stringToByteArray(字符串:字符串) -  GT; [UINT8] {
    VAR字节:[UINT8] = [];
    在string.utf8 code {
        bytes.append(UINT8(code));
    }
    返回字节;
}FUNC byteArrayToBase64(字节数:[UINT8]) - GT;字符串{
    让NSData的:NSData的NSData的=(字节数:字节(字节),长度:bytes.count)
    让base64En codeD:的NSString = nsdata.base64En codedStringWithOptions(NSDataBase64EncodingOptions(rawValue:0));
    返回字符串(base64En codeD);
}FUNC base64ToByteArray(base64String:字符串) - GT; [UINT8] {
    让NSData的:NSData的NSData的=(base64En codedString:base64String,选择:NSDataBase64DecodingOptions(rawValue:0))!
    让base64De codeD:的NSString =的NSString(数据:NSData的,编码:NSUTF8StringEncoding)!
    返回stringToByteArray(字符串(base64De codeD));
}/ *与128以下或更高更换127产生错误* /
变种的TestString = byteArrayToBase64([127]);
base64ToByteArray(的TestString)


解决方案

该问题是在这里:

 让base64De codeD:的NSString =的NSString(数据:NSData的,编码:NSUTF8StringEncoding)!

您去codeD数据转换为字符串。这个失败
[128] ,因为不重新present一个有效的UTF-8序列。

下面是避免了中间串一个版本:

  FUNC base64ToByteArray(base64String:字符串) -  GT; [UINT8] {
    让NSData的:NSData的NSData的=(base64En codedString:base64String,选择:NSDataBase64DecodingOptions(rawValue:0))!
    //创建所需大小的数组...
    VAR字节= [UINT8](计数:nsdata.length,repeatedValue:0)
    // ...并与数据填充它
    nsdata.getBytes(安培;字节)
    返回字节
}

说明:


  • 选项:NSDataBase64DecodingOptions(rawValue:0)可以简化
    选项:无

  • 有一些不必要的类型标注和转换在code。

  • 您的功能崩溃,如果即basestring 不是有效的Base64编码字符串。
    你可以改变它返回一个可选的。

然后,它是这样的:

  FUNC byteArrayToBase64(字节数:[UINT8]) -  GT;字符串{
    让NSData的NSData的=(字节数:字节,长度:bytes.count)
    让base64En codeD = nsdata.base64En codedStringWithOptions(无);
    返回base64En codeD;
}FUNC base64ToByteArray(base64String:字符串) - GT; [UINT8] {
    如果让NSData的NSData的=(base64En codedString:base64String,选择:无){
        VAR字节= [UINT8](计数:nsdata.length,repeatedValue:0)
        nsdata.getBytes(安培;字节)
        返回字节
    }
    返回nil //输入无效
}

实例:

 让我们的TestString = byteArrayToBase64([127,128,0,130]);
的println(的TestString)//输出:f4AAgg ==
如果让结果= base64ToByteArray(的TestString){
    的println(结果)//输出:[127,128,0,130]
}其他{
    的println(失败)
}


更新雨燕2 / X code 7:

  FUNC byteArrayToBase64(字节数:[UINT8]) -  GT;字符串{
    让NSData的NSData的=(字节数:字节,长度:bytes.count)
    让base64En codeD = nsdata.base64En codedStringWithOptions([]);
    返回base64En codeD;
}FUNC base64ToByteArray(base64String:字符串) - GT; [UINT8] {
    如果让NSData的NSData的=(base64En codedString:base64String,选项:[]){
        VAR字节= [UINT8](计数:nsdata.length,repeatedValue:0)
        nsdata.getBytes(安培;字节,长度:bytes.count)
        返回字节
    }
    返回nil //输入无效
}让我们的TestString = byteArrayToBase64([127,128,0,130]);
打印(的TestString)//输出:f4AAgg ==
如果让结果= base64ToByteArray(的TestString){
    打印(结果)//输出:[127,128,0,130]
}其他{
    打印(失败)
}

To keep this simple, I'll only be encoding/decoding a single byte.

If I encode the byte 127, I get the base64 string "fw==" which can be successfully decoded back to byte 127. If, however, I encode a byte ≥ 128, then even though I can produce a base64 string without error (for example, byte 128 gives the string "gA=="), I get an error when I try to decode it.

Here's my code which can be copy-pasted into any Xcode playground to reproduce the problem:

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)

解决方案

The problem is here:

let base64Decoded: NSString = NSString(data: nsdata, encoding: NSUTF8StringEncoding)!

You convert the decoded data to a string. This fails for [128] because that does not represent a valid UTF-8 sequence.

Here is a version that avoids the intermediate string:

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
}

Remarks:

  • options: NSDataBase64DecodingOptions(rawValue: 0) can be simplified to options: nil.
  • There are some unnecessary type annotations and conversions in your code.
  • Your function crashes if baseString is not a valid Base64 string. You could change it to return an optional.

Then it would look like this:

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
}

Example usage:

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")
}


Update for 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")
}

这篇关于某些解码Base64编码字符串时错误,但不是别人的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆