为了保持这一点,我只会对单个字节进行编码/解码。
如果我对字节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)
答案 0 :(得分:4)
问题在于:
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")
}