Swift中生成符合哈希校验要求的字符串:移除引号转义反斜杠且保留换行回车转义
解决自定义JSON编码器中保留转义序列字面量的问题
核心问题分析
你现在的需求很明确:生成的字符串要满足两个关键条件:
- 双引号不需要转义(直接显示
",而非\") - 字符串中的
\n和\r要以字面量转义序列存在(即显示为\n/\r,而不是被解析成实际的换行/回车)
当前你的编码器代码中,#""\#(string)""#的写法确实避免了双引号的转义,但问题在于:字符串插值会把原始string中的控制字符(比如实际的\n换行符)直接解析成换行,而不是保留成\n的字面量形式。
解决方案:转换控制字符为字面量转义序列
我们需要先对输入的字符串进行预处理,把其中实际的换行/回车字符替换成对应的字面量转义序列(也就是用\\n代替\n,\\r代替\r),这样最终生成的字符串里就会保留\n和\r的写法,同时双引号依然不被转义。
修改你的encode(_:depth:)方法中的.string分支代码如下:
private func encode(_ value: JSON, depth: Int) throws -> String { switch value { case let .string(string): // 预处理:把实际的换行/回车字符替换成字面量转义序列 let processedString = string .replacingOccurrences(of: "\n", with: "\\n") .replacingOccurrences(of: "\r", with: "\\r") // 用Raw String包裹,避免双引号被转义 let zeString = #""\#(processedString)""# return zeString case let .number(digits): return digits case let .bool(value): return value ? "true" : "false" case let .object(object): return try encode(object: object, depth: depth) case let .array(array): return try encode(array: array, depth: depth) case .null: return "null" } }
为什么这样有效?
- 当你调用
.replacingOccurrences(of: "\n", with: "\\n")时,是把字符串中实际的换行字符(ASCII码0x0A)替换成了两个字符:反斜杠(\)和字母n,这样在最终的字符串里就会显示为\n。 - 用Raw String(
#""..."#")包裹处理后的字符串,确保双引号不会被自动转义,直接输出为",完全符合你要求的格式。
扩展说明
如果你的字符串中还有其他需要保留的转义序列(比如制表符\t),可以直接在预处理环节添加对应的替换规则:
let processedString = string .replacingOccurrences(of: "\n", with: "\\n") .replacingOccurrences(of: "\r", with: "\\r") .replacingOccurrences(of: "\t", with: "\\t")
这样处理后,生成的字符串就能同时满足双引号不转义、转义序列以字面量保留的要求,和Android端的格式保持一致,顺利通过哈希校验。
内容的提问来源于stack exchange,提问作者Async-
相关产品推荐
相关产品推荐

