Swift IOS 中的 XOR 加密

XOR Encryption in Swift IOS

尝试将 Below Objective C 的 XOR 加密方法转换为 Swift,但出现类似 "Could nt find overload for 'subscript' that accept supplied argument" 的错误。任何帮助将不胜感激。

Objective C

+(NSString *) encryptDecrypt:(NSString *)input staticKey:(NSString *) staticKey
{
    const char *key = [staticKey UTF8String];; //Can be any chars, and any size array
    NSMutableString *output = [[NSMutableString alloc] init];

    for(int i = 0; i < input.length; i++) {
        char c = [input characterAtIndex:i];
        c ^= key[i % sizeof(key)/sizeof(char)];
        [output appendString:[NSString stringWithFormat:@"%c", c]];
    }
    return output;
} 

Swift

func encryptDecrypt(input: String, staticKey: String) -> String {
    let cstr = staticKey.cStringUsingEncoding(NSUTF8StringEncoding)
    var output: NSMutableString = NSMutableString()
    for (index, element) in enumerate(input) {
        // for var i = 0; i < input.length; i++ {
        var c: Character = element
        let char = c ^ cstr[index % sizeof(cstr) / sizeof(Character)]
        output.appendString("\(c)")
    }
    return output as String
}

免责声明: 正如评论中所解释的那样,在 UTF8 字符串上使用这种位操作是不安全的,并且对于任意输入不会按预期工作。

我实际上不确定原始 Objective-C 代码是否符合您的要求。 sizeof(key)char 指针(在我的平台上是 8)的内存地址的大小,而不是 UTF8 数组的长度。最重要的是,sizeof(char) 应始终为 1。您可能想改用 strlen

无论如何,Swift 2 中的(更正)Objective-C 代码的等价物可能是这样的

func encryptDecrypt(input: String, staticKey: String) -> String? {
    let key = staticKey.utf8
    let bytes = input.utf8.enumerate().map({
         ^ key[key.startIndex.advancedBy([=10=] % key.count)]
    })
    return String(bytes: bytes, encoding: NSUTF8StringEncoding)
}

测试片段

let key = "12345"
let string = "abcdefghijklmnopqrstuvwxyz"

let encrypted = encryptDecrypt(string, staticKey: key)!
let decrypted = encryptDecrypt(encrypted, staticKey: key)!

print(string)
print(encrypted)
print(decrypted)

会打印出来

abcdefghijklmnopqrstuvwxyz
PPPPPWU[]_Z^^ZZACAGADDDLLK
abcdefghijklmnopqrstuvwxyz

对于 Swift 1.2,您必须进行一些小改动:

func encryptDecrypt(input: String, staticKey: String) -> String? {
    let key = staticKey.utf8
    let keyLength = distance(key.startIndex, key.endIndex)
    let bytes = map(enumerate(input.utf8)) {
         ^ key[advance(key.startIndex, [=13=] % keyLength)]
    }
    return String(bytes: bytes, encoding: NSUTF8StringEncoding)
}

更新: 以下代码片段更接近原始 Objective-C 代码并且适用于任意字符串:

func encryptDecrypt(input: NSString, staticKey: NSString) -> NSString? {
    let chars = (0..<input.length).map({
        input.characterAtIndex([=14=]) ^ staticKey.characterAtIndex([=14=] % staticKey.length)
    })
    return NSString(characters: chars, length: chars.count)
}