【问题标题】:Convert string to base64 byte array in swift and java give different value在swift和java中将字符串转换为base64字节数组给出不同的值
【发布时间】:2018-05-31 14:24:23
【问题描述】:

在 android 的情况下一切正常。我也想在 iOS 中实现相同的功能,但获得不同的值。请查看下面的图片说明。

在 Java/Android 案例中:

我尝试将字符串转换为 java 中的 base64 字节数组,例如

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

输出:

在 Swift3/iOS 案例中:

我尝试在 swift 中将字符串转换为 base64 字节数组,例如

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

输出:

【问题讨论】:

  • 不同的值? -55201 似乎几乎“相等”,不是吗?我的意思是在 iOS 中是 UInt8(在你的屏幕截图中可以看到),在 Java 中我猜是 Int8,意思是无符号与有符号(所以 0 到 255 和 -127 到 128)。
  • 非常感谢@Larme 的回答
  • @Larme,我还想知道一件事。如何将 Int8/UInt8 字节数组转换为可读的字符串格式?在这里使用这种方式我尝试转换为字符串。但它打印的不是有效的 UTF-8 序列。 if let string = String(data: data, encoding: .utf8) { print(string) } else { print("不是一个有效的 UTF-8 序列") }
  • stackoverflow.com/questions/39075043/… 或者如果您想要“int”而不是“hex”,请使用不同的格式 developer.apple.com/library/content/documentation/Cocoa/…

标签: ios arrays encryption swift3 base64


【解决方案1】:

终于解决了:

这是由于有符号和无符号整数,意味着无符号与有符号(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 在大多数情况下意味着字符串的结尾,它可能存在于字节序列的中间。

    所以您已经有两种逐字节打印的方式,它们显示了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
    

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

    【讨论】:

    • Matic 非常感谢您的回答,我还想知道一件事。如何将 Int8/UInt8 字节数组转换为可读的字符串格式?在这里使用这种方式我尝试转换为字符串。但它打印的不是有效的 UTF-8 序列。 if let string = String(data: data, encoding: .utf8) { print(string) } else { print("不是一个有效的 UTF-8 序列") }
    • @jazzbpn 请检查我的编辑,如果这解释了,请告诉我。
    猜你喜欢
    • 2012-07-21
    • 2014-12-22
    • 1970-01-01
    • 2016-06-07
    • 2016-10-21
    • 2010-10-26
    • 1970-01-01
    • 2016-01-21
    • 2012-07-12
    相关资源
    最近更新 更多