Xor 为 uint16 或 uint32 的字符串

Xor a string that is uint16 or uint32

我正在尝试重新创建我在 JAVA 到 swift 中创建的以下逻辑:

public String xorMessage(String message, String key) {

    try {
        if (message == null || key == null) return null;

        char[] keys = key.toCharArray();
        char[] mesg = message.toCharArray();

        int ml = mesg.length;
        int kl = keys.length;
        char[] newmsg = new char[ml];

        for (int i = 0; i < ml; i++) {
            newmsg[i] = (char)(mesg[i] ^ keys[i % kl]);
        }//for i

        return new String(newmsg);
    } catch (Exception e) {
        return null;
    }

我在 swift3 中编码时到达这里:

import UIKit
import Foundation


let t = "22-Jun-2017 12:30 pm"
let m = "message"
print(UInt8(t))


let a :[UInt8] = Array(t.utf8)
let v  = m.characters.map{String ([=11=]) }
print(v)
func encodeWithXorByte(key: UInt8 , Input : String) -> String {
    return String(bytes: Input.utf8.map{[=11=] ^ key}, encoding: String.Encoding.utf8) ?? ""

}

var ml :Int = Int( m.characters.count )


var kl :Int = Int (t.characters.count)



var f = [String]()
for i in 0..<ml{

    let key = a[i%kl]
    let input = v[i]


    f.append(String(bytes: input.utf8.map{[=11=] ^ key} , encoding : String.Encoding.utf8)!)


   // f.append(<#T##newElement: Character##Character#>)
    //m[i] = input.utf8.map{[=11=] ^ key}

}

我正在尝试获取一个字符串(消息),该字符串(消息)已与传递到上述函数的密钥进行了异或运算。但是我在 swift 中的代码不起作用,因为它正在返回字符数组,我想要一个字符串,如果我尝试将字符数组转换为字符串,它不会在字符串中显示像 \u{0001} 等的 unicode ...

假设我得到以下输出:

["_", "W", "^", "9", "\u{14}", "\t", "H"]

然后我尝试转换为字符串,我得到这个:

_W^9H

我要:

_W^9\u{14}\tH

请帮忙。

存在不同的问题。首先,如果您打算打印 "unprintable" 字符串中的字符 \u{} 转义然后你可以使用 .debugDescription 方法。示例:

let s = "a\u{04}\u{08}b"
print(s) // ab
print(s.debugDescription) // "a\u{04}\u{08}b"

接下来,您的 Swift 代码将字符串转换为 UTF-8,异或字节 然后将结果转换回字符串。这很容易失败 如果异或字节序列不是有效的 UTF-8。

Java 代码在 UTF-16 代码单元上运行,因此等价于 Swift 代码将是

func xorMessage(message: String, key: String) -> String {
    let keyChars = Array(key.utf16)
    let keyLen = keyChars.count

    let newMsg = message.utf16.enumerated().map {  ^ keyChars[[=11=] % keyLen] }
    return String(utf16CodeUnits: newMsg, count: newMsg.count)
}

示例:

let t = "22-Jun-2017 12:30 pm"
let m = "message"
let encrypted = xorMessage(message: m, key: t)
print(encrypted.debugDescription) // "_W^9\u{14}\tH"

最后,即使那样也会产生意想不到的结果,除非你限制 输入(键和消息)到 ASCII 字符。示例:

let m = "" 
print(Array(m.utf16).map { String([=13=], radix: 16)} ) // ["d83d", "de00"]

let t = "a€" 
print(Array(t.utf16).map { String([=13=], radix: 16)} ) // ["61", "20ac"]

let e = xorMessage(message: m, key: t)
print(Array(e.utf16).map { String([=13=], radix: 16)} ) // ["fffd", "feac"]

let d = xorMessage(message: e, key: t)
print(Array(d.utf16).map { String([=13=], radix: 16)} ) // ["ff9c", "fffd"]

print(d) // ワ�
print(d == m) // false

问题是异或运算产生了无效的 UTF-16 序列 (一个不平衡的代理对),然后由 "replacement character"U+FFFD.

我不知道 Java 是如何处理的,但是 Swift 字符串不能无效 Unicode 标量值,所以唯一的解决方案是表示 结果作为 [UInt16] 数组而不是 String.