在swift和java中将字符串转换为base64字节数组给出不同的值

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在swift和java中将字符串转换为base64字节数组给出不同的值相关的知识,希望对你有一定的参考价值。

安卓的一切都很完美。我想在ios中实现相同的功能,但获得不同的值。请查看以下图片说明。

在Java / android案例中:

我试图将字符串转换为java中的base64字节数组

 byte[] data1 = Base64.decode(balance, Base64.DEFAULT);

输出:enter image description here

在Swift3 / iOS案例中:

我尝试将字符串转换为swift中的base64字节数组

let data:Data = Data(base64Encoded: balance, options: NSData.Base64DecodingOptions(rawValue: 0))!
let data1:Array = (data.bytes)

输出:enter image description here

答案

终于解决了:

这是由于有符号和无符号整数,意味着无符号vs有符号(因此0到255和-127到128)。在这里,我们需要将UInt8数组转换为Int8数组,因此问题将得到解决。

let intArray = data1.map { Int8(bitPattern: $0) }
另一答案

在任何情况下,您都不应该像以前那样比较2个系统上的数据。这适用于所有类型,但特别适用于原始数据。

如果没有额外的上下文,原始数据是不可能的,这意味着任何提供它们的系统都可以选择如何呈现它们(原始数据可能代表UTF8中的某些文本或某些ASCII,可能是jpeg图像或png或原始RGB像素数据,它可能是音频样本或其他)。在你的情况下,一个系统将它们显示为带符号的8位整数列表,而另一个系统使用8位无符号整数表示相同的事物。例如,另一个系统可能会显示一个看起来完全不同的十六进制字符串。

正如@Larme已经提到过的那些看起来一样,因为假设一个系统使用signed和其他无符号值是安全的。因此,要从signed(Android)转换为unsigned(iOS),您需要将负值转换为unsigned = 256+signet,例如-55 => 256 + (-55) = 201

如果您确实需要在您的情况下比较数据,最好将它们作为原始数据保存到某个文件中。然后将该文件传输到另一个系统,并将原始原始数据与文件中的原始数据进行比较,以检查是否存在差异。

编辑(来自评论):

将原始数据作为字符串打印是一个问题,但有几种方法。问题是许多字节不能作为字符串打印,可能是空格或一些保留代码,但问题是0的值意味着大多数情况下字符串的结尾可能存在于字节序列的中间。

因此,您已经有两种逐字节打印方式,显示Int8Uint8对应的值。正如评论中所描述的那样,直接转换为字符串可能不那么容易

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)

打印结果是:

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþ

另一种流行的方法是使用十六进制字符串。它可以显示为:

let hexString = data.reduce("", { $0 + String(format: "%02hhx",$1) })
print(hexString)

并且使用与之前相同的数据:

000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff

我希望这已经足够了,但一般来说,你可以用字节数组做任何事情并显示它们。例如,如果有意义的话,你可以创建一个图像处理字节为每个组件的RGB 8位。这可能听起来很愚蠢,但如果你正在寻找一些模式,它可能是一个很机智的解决方案。

以上是关于在swift和java中将字符串转换为base64字节数组给出不同的值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 3 中将 captureStillImageAsynchronously(sampleBuffer) 转换为 base64 编码

如何在 ios 中将 Base64 编码的 NSString 转换为字节数组(Java)?

无法在iOS swift中将base64string解码为uiimage,但在android中工作正常[重复]

如何在 PHP 中将图像从 base 64 转换为它们的文件类型?

如何在 Java 中将字节数组转换为 Base64?

如何在IOS中将视频文件转换为Base64字符串?