某些解码Base64编码字符串时错误,但不是别人 [英] Error when decoding certain Base64 strings, but not others
问题描述
要保持这个简单,我将只编码/单字节进行解码。
如果我带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 tooptions: 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屋!