解码某些 Base64 字符串时出错,但不是其他字符串
Posted
技术标签:
【中文标题】解码某些 Base64 字符串时出错,但不是其他字符串【英文标题】:Error when decoding certain Base64 strings, but not others 【发布时间】:2014-11-09 09:38:53 【问题描述】:为了简单起见,我将只编码/解码一个字节。
如果我对字节 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)
【问题讨论】:
【参考方案1】:问题出在这里:
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: NSDataBase64DecodingOptions(rawValue: 0)
可以简化
到options: nil
。
您的代码中有一些不必要的类型注释和转换。
如果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")
【讨论】:
以上是关于解码某些 Base64 字符串时出错,但不是其他字符串的主要内容,如果未能解决你的问题,请参考以下文章