Swift base64EncodedString 从同一个字符串生成不同的值?

Swift base64EncodedString produces different values from same string?

我运行在swift中使用此代码:

var testBody = [String:Any]()
testBody["f1"] = "1234"
testBody["f2"] = "4321"
var o2 = [String:Any]()
o2["ttnn"] = "wedcfqv w"
o2["ttnn1"] = "mwkcd wmd 234"
testBody["o2"] = o2
        
let bodyData1:Data = try JSONSerialization.data(withJSONObject:testBody,options: JSONSerialization.WritingOptions.prettyPrinted)
let bodyDataBase641 = bodyData1.base64EncodedString()
        
print("bodyData1: \(bodyDataBase641)")

首先 运行 bodyData1 打印给出:

bodyData1: ewogICJmMSIgOiAiMTIzNCIsCiAgImYyIiA6ICI0MzIxIiwKICAibzIiIDogewogICAgInR0bm4xIiA6ICJtd2tjZCB3bWQgMjM0IiwKICAgICJ0dG5uIiA6ICJ3ZWRjZnF2IHciCiAgfQp9

第二个 运行 bodyData1 打印给出了这个:

bodyData1: ewogICJvMiIgOiB7CiAgICAidHRubiIgOiAid2VkY2ZxdiB3IiwKICAgICJ0dG5uMSIgOiAibXdrY2Qgd21kIDIzNCIKICB9LAogICJmMiIgOiAiNDMyMSIsCiAgImYxIiA6ICIxMjM0Igp9

我最初的期望是能够获得完全相同的编码 base 64 字符串,只要我对相同的正文数据进行编码。

但是,运行将此代码编译两次,returns 两个 不同的 base 64 编码字符串,如 bodyData1 日志中所示。

那么,我怎样才能确保只要正文保持不变,编码后的 64 位字符串也将始终相同?

那是因为您将值存储在字典中,而字典是:

Every dictionary is an unordered collection of key-value pairs.

print(testBody) 在编码之前,您会看到顺序发生了变化。

查看 Apple 的词典文档以获取更多信息:Docs

使用在线 base 64 解码器解码字符串会向您展示正在发生的事情。第一个解码为:

{
  "f1" : "1234",
  "f2" : "4321",
  "o2" : {
    "ttnn1" : "mwkcd wmd 234",
    "ttnn" : "wedcfqv w"
  }
}

第二个解码为:

{
  "o2" : {
    "ttnn" : "wedcfqv w",
    "ttnn1" : "mwkcd wmd 234"
  },
  "f2" : "4321",
  "f1" : "1234"
}

JSON 键默认是无序的。如果您想要相同的字符串,一种方法是通过提供选项 sortedKeys:

对键进行排序
try JSONSerialization.data(
    withJSONObject: testBody, 
    options: [.prettyPrinted, .sortedKeys]
)