在swift和java中将字符串转换为base64字节数组赋予不同的值
Incase of android一切正常。我想在iOS中实现相同的功能,但获得不同的值。请用下面的图片检查描述。在swift和java中将字符串转换为base64字节数组赋予不同的值
在Java/Android的案例:
我试图将字符串转换为base64字节数组中的java像
byte[] data1 = Base64.decode(balance, Base64.DEFAULT);
在Swift3/iOS案例:
我试图将字符串转换为base64字节数组中迅速像
let data:Data = Data(base64Encoded: balance, options: NSData.Base64DecodingOptions(rawValue: 0))!
let data1:Array = (data.bytes)
终于解决:
这是由于签署和无符号整数,意味着无符号与有符号(所以0到255和-127到128)。这里,我们需要将UInt8数组转换为Int8数组,因此问题就解决了。
let intArray = data1.map { Int8(bitPattern: $0) }
在任何情况下,你应该尝试将数据在2个系统中,你只是做的方式进行比较。这适用于所有类型,但特别适用于原始数据。
如果没有附加的上下文,原始数据不会呈现,这意味着任何呈现它们的系统可能会选择如何呈现它们(原始数据可能代表一些UTF8或某些ASCII文本,可能是jpeg图像或png或原始RGB像素数据,它可能是一个音频样本或其他)。在你的情况下,一个系统将它们显示为已签名8位整数列表,而另一个系统使用8位无符号整数表示同一事物。另一个系统可能会显示一个看起来完全不同的十六进制字符串。
正如@Larme已经提到的,这些看起来是一样的,因为假定一个系统使用带符号和其他无符号值是安全的。因此,要将已签名(Android)转换为未签名(iOS),您需要将负值转换为unsigned = 256+signet
,例如-55 => 256 + (-55) = 201
。
如果您确实需要比较您的案例中的数据,最好将它们作为原始数据保存到某个文件中。然后将该文件传输到另一个系统,并将本机原始数据与文件中的数据进行比较,以检查是否存在差异。
编辑(从评论):
打印原始数据作为一个字符串是一个问题,但有几个方法。问题在于许多字节不能作为字符串打印,可能是空格或一些保留的代码,但大多数问题是值为0意味着在大多数情况下字符串的结尾可能存在于字节序列的中间。
因此,您已经有2种逐字节打印的方式,它显示Int8
或Uint8
相应的值。如在注释中所描述直接转换为字符串可能不工作容易,因为
let string = String(data: data, encoding: .utf8) // Will return nil for strange strings
一个数据转换为字符串可以是每个字节转换为对应的字符的方式。检查验证码:
let characterSequence = data.map { UnicodeScalar($0) } // Create an array of characters from bytes
let stringArray = characterSequence.map { String($0) } // Create an array of strings from array of characters
let myString = stringArray.reduce("", { $0 + $1 }) // Convert an array of strings to a single string
let myString2 = data.reduce("", { $0 + String(UnicodeScalar($1)) }) // Same thing in a single line
然后对其进行测试我使用:
let data = Data(bytes: Array(0...255)) // Generates with byte values of 0, 1, 2... up to 255
let myString2 = data.reduce("", { $0 + String(UnicodeScalar($1)) })
print(myString2)
打印结果是:
!"#$%&'()*+,-./:;<=>[email protected][\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ
然后另一种流行的方法是使用一个十六进制字符串。它可以显示为:
let hexString = data.reduce("", { $0 + String(format: "%02hhx",$1) })
print(hexString)
而且具有相同的数据结果之前是:
000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff
我希望这是足够的,但总的来说,你可以做的字节数组和相当多的东西给他们看。例如,如果它有意义,您可以创建一个图像处理字节为每个组件8位RGB。这可能听起来很愚蠢,但如果你正在寻找一些模式,这可能是一个非常机智的解决方案。
马蒂奇非常感谢你的回答,我想知道更多的事情。如何将Int8/UInt8字节数组转换为可读的字符串格式?在这里使用这种方式我尝试转换为字符串。但它不打印有效的UTF-8序列。 如果让字符串=字符串(数据:数据,编码:.utf8){ 打印(串) }其他{ 打印( “不是一个合法的UTF-8序列”) } – jazzbpn
@jazzbpn请检查我的编辑,让我知道这是否解释是。 –
不同的值? '-55' vs'201'似乎几乎“等于”,不是吗?我的意思是在iOS中,它是'UInt8'(它在你的屏幕截图中看到),而在Java中,我猜它是'Int8',意思是无符号与带符号(所以0到255和-127到128)。 – Larme
非常感谢你的回答@Larme – jazzbpn
@ Larme,我想知道一件事。如何将Int8/UInt8字节数组转换为可读的字符串格式?在这里使用这种方式我尝试转换为字符串。但它不打印有效的UTF-8序列。如果让string = String(data:data,encoding:.utf8){print(string)} else {print(“不是有效的UTF-8序列”)} – jazzbpn