如何将Swift字符串转换为C字节数组并返回Swift String

时间:2017-12-13 01:48:37

标签: swift unicode-string

我正在尝试将Swift字符串作为[UInt8]字节数组,然后从C代码返回相同的字节数组并将其转换回原始的Swift字符串。我正在尝试保留unicode(因此在转换/操作方面没有任何损失)。我收到错误“无法将类型'String.Encoding'的值转换为解密函数中转换行上的预期参数类型'UInt'。提前感谢您的帮助!

    // function to encrypt a string with custom "C" code and encode the result into a hex string
func EncryptString( password: String, stringToEncrypt: String) ->String {

    var hexStr = ""

    // convert the String password into utf8 bytes
    let pw = password.data(using: String.Encoding.utf8, allowLossyConversion:false)
    var passwordBytes : [UInt8] = Array(pw!)

    // convert the string to encrypt into utf8 bytes
    let bytes = stringToEncrypt.data(using: String.Encoding.utf8, allowLossyConversion:false)
    var buf : [UInt8] = Array(bytes!)

    // encrypt the string to encrypt with the Unicode password (both are Unicode in Swift)
    encryptData(&passwordBytes, Int32(password.count), &buf, Int32(stringToEncrypt.count))

    // turn the now encrypted "stringToEncrypt" into two character hex values in a string
    for byte in buf {
        hexStr.append(String(format:"%2X", byte))
    }

    // return the encrypted hex encoded string to the caller...
    return hexStr
}


func DecryptString( password: String, hexStringToDecrypt: String) ->String {

    var decryptedStr = ""

    // convert the String password into utf8 bytes
    let pw = password.data(using: String.Encoding.utf8, allowLossyConversion:false)
    var passwordBytes : [UInt8] = Array(pw!)

    // convert the string to encrypt into utf8 bytes
    let bytes = hexStringToDecrypt.data(using: String.Encoding.utf8, allowLossyConversion:false)
    var buf : [UInt8] = Array(bytes!)

    // encrypt the string to encrypt with the Unicode password (both are Unicode in Swift)

    let bytecount = password.count
    decryptData(&passwordBytes, Int32(password.count), &buf, Int32(hexStringToDecrypt.count))
            // turn the now encrypted "hexStringToDecrypt" into int values here is where I get error: Cannot convert value of type 'String.Encoding' to expected argument type 'UInt'
    var unicode_str = NSString(bytes: buf, length: bytecount, encoding: NSUTF32LittleEndianStringEncoding)

    // return the encrypted hex encoded string to the caller...
    return unicode_str
}

}

1 个答案:

答案 0 :(得分:3)

使用Swift 3/4时,最好使用Data类型代替UInt8

String转换为Data

let dat = string.data(using:.utf8)

Data转换为String

let str = String(data:dat, encoding:.utf8)

以下是使用Data代替UInt8的示例加密,这不是生产代码,它至少缺少错误处理。

func aesCBCEncrypt(data:Data, keyData:Data, ivData:Data) -> Data {
        let cryptLength = size_t(kCCBlockSizeAES128 + data.count + kCCBlockSizeAES128)
        var cryptData = Data(count:cryptLength)
        var numBytesEncrypted :size_t = 0

        let cryptStatus = cryptData.withUnsafeMutableBytes {cryptBytes in
            data.withUnsafeBytes {dataBytes in
                keyData.withUnsafeBytes {keyBytes in
                    ivData.withUnsafeBytes {ivBytes in
                        CCCrypt(CCOperation(kCCEncrypt),
                                CCAlgorithm(kCCAlgorithmAES),
                                CCOptions(kCCOptionPKCS7Padding),
                                keyBytes, keyData.count,
                                ivBytes,
                                dataBytes, data.count,
                                cryptBytes, cryptLength,
                                &numBytesEncrypted)
                    }}}}

    cryptData.count = (cryptStatus == kCCSuccess) ? numBytesEncrypted : 0

    return cryptData;
}