Character encoding 在swift 3中将base64编码字符串转换为普通字符串

Character encoding 在swift 3中将base64编码字符串转换为普通字符串,character-encoding,swift3,base64,Character Encoding,Swift3,Base64,我想在Swift 3中转换以下base64编码的字符串: dfYcSGpvBqyzvkAXkdbHDA== 对于其等价的字符串: uöHjo¬³¾@‘ÖÇ 以下网站做得很好: PHP的函数base64\u decode也是如此。该功能的主要功能是: 如果输入包含base64之外的字符,则返回FALSE 字母表 但是我不能在Swift 3中做同样的事情。以下代码也不能完成此任务: func convertBase64ToNormalString(base64String:String)-&

我想在Swift 3中转换以下base64编码的
字符串

dfYcSGpvBqyzvkAXkdbHDA==
对于其等价的
字符串

uöHjo¬³¾@‘ÖÇ
以下网站做得很好:

PHP的函数
base64\u decode
也是如此。该功能的主要功能是:

如果输入包含base64之外的字符,则返回FALSE 字母表

但是我不能在Swift 3中做同样的事情。以下代码也不能完成此任务:

func convertBase64ToNormalString(base64String:String)->String!{
   let decodedData = Data(base64Encoded: base64String, options:    Data.Base64DecodingOptions())
   let bytes = decodedData?.bytes
   return String(bytes: bytes, encoding: NSUTF8StringEncoding)
}
以下是有关为什么需要将base64字符串转换为字符串的上下文信息: 我的Php开发人员希望我发送使用AES算法加密的所有API参数值。为此,我正在使用。 他给了我十六进制格式的AES密钥(我在my中提到过)和base64格式的iv密钥(上面给出),他指示我在使用之前解码base64密钥,因为他在PHP代码中也做了同样的操作。以下是他的PHP加密和解密代码:

function encryptParamAES($plaintext, $encryptionEnabled = true) {
    if (! $encryptionEnabled) {
        return $plaintext;
    }
    // --- ENCRYPTION ---

    // Constants =========================================================
    // the key should be random binary, use scrypt, bcrypt or PBKDF2 to
    // convert a string into a key
    // key is specified using hexadecimal
    $key = pack ( 'H*', "dcb04a9e103a5cd8b53763051cef09bc66abe029fdebae5e1d417e2ffc2a07a4" );
    // create a random IV to use with CBC encoding
    $iv_size = 16;
    $iv = base64_decode ( "dfYcSGpvBqyzvkAXkdbHDA==" );

    // End Of constants ===================================================

    // echo "IV: " . base64_encode ( $iv ) . "\n<br>";
    // echo "IV Size: " . $iv_size . "\n<br>";

    // show key size use either 16, 24 or 32 byte keys for AES-128, 192
    // and 256 respectively

    // $key_size = strlen ( $key );
    // echo "Key size: " . $key_size . "\n<br><br>";

    // creates a cipher text compatible with AES (Rijndael block size = 128)
    // to keep the text confidential
    // only suitable for encoded input that never ends with value 00h
    // (because of default zero padding)
    $ciphertext = mcrypt_encrypt ( MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv );

    // prepend the IV for it to be available for decryption
    $ciphertext = $iv . $ciphertext;

    // encode the resulting cipher text so it can be represented by a string
    $ciphertext_base64 = base64_encode ( $ciphertext );

    return $ciphertext_base64;
}


function decryptParamAES($ciphertext_base64, $encryptionEnabled = true) {
    if (! $encryptionEnabled) {
        return $ciphertext_base64;
    }
    // --- DECRYPTION ---

    // Constants =========================================================
    // the key should be random binary, use scrypt, bcrypt or PBKDF2 to
    // convert a string into a key
    // key is specified using hexadecimal
    $key = pack ( 'H*', "dcb04a9e103a5cd8b53763051cef09bc66abe029fdebae5e1d417e2ffc2a07a4" );
    // create a random IV to use with CBC encoding
    $iv_size = 16;
    $iv = base64_decode ( "dfYcSGpvBqyzvkAXkdbHDA==" );

    // End Of constants ===================================================

    $ciphertext_dec = base64_decode ( $ciphertext_base64 );

    // retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
    $iv_dec = substr ( $ciphertext_dec, 0, $iv_size );

    // retrieves the cipher text (everything except the $iv_size in the front)
    $ciphertext_dec = substr ( $ciphertext_dec, $iv_size );

    // may remove 00h valued characters from end of plain text
    $plaintext_dec = mcrypt_decrypt ( MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec );
    return rtrim ( $plaintext_dec );
}

结果是:
u?Hjo???@?

看你修改过的问题,你试图把这个base-64字符串作为AES算法中的
iv
。我可以理解为什么您想知道如何将生成的
数据
转换为
字符串
,但您不应该这样做。是的,有一个
AES
的格式副本,它期望
iv
作为字符串。但还有另一种格式副本需要
数组
。因此,正如MartinR在中所说,构建一个
UInt8
数组,如下所示:

let iv = Array(Data(base64Encoded: "dfYcSGpvBqyzvkAXkdbHDA==")!)
产生的
iv
是一个
数组(也称为
[UInt8]
)。您可以将其与
AES
函数一起使用

下面是我最初关于将
数据
对象转换为UTF8字符串的讨论。但关键的信息是,你不应该这样做。只需构建
UInt8
数组,并将其与库的
AES
函数一起使用即可


查看另一个问题(),您在评论中透露您正在处理AES密钥。我怀疑我们正在处理一个类似的问题(虽然这是32字节的数据,而这里我们有16字节)

总之,我建议您完全放弃“如何获取此base-64字符串中捕获的数据的字符串表示”这一查询行。如果它是一个加密密钥(或某个令牌或任何东西),不要麻烦尝试将其表示为字符串。(这是base-64存在的理由,它创建非字符串数据的可传输字符串表示形式。)

我建议你退一步,描述一下你试图解决的更广泛的问题。停止尝试从这些二进制有效负载创建字符串。在代码段中,您成功地从base-64字符串创建了一个
数据。我认为,真正的问题不是“我现在如何从中获取字符串?”,而是“我如何处理数据?”

如果没有更多关于你从哪里获得这些数据以及这些数据的用途的上下文,我们无法回答这个问题

顺便说一下,我对你的问题的原始答案如下


问题是base-64字符串转换为16字节的数据,其十六进制表示为

75f61c48 6a6f06ac b3be4017 91d6c70c 75f61c48 6a6f06ac b3be4017 91d6c70c 但该有效负载不是有效的UTF8字符串。第三个字节
1c
与UTF8字符串不一致。如果你看一下,它说如果一个字节在
f6
fb
的范围内,第二个字节是,那么字符由该字节和以下两个字节组成,这两个字节都应该在
21
7e
a0
ff
的范围内,而
1c
不是

因此,这根本不是有效的UTF8字符串。显然,您正在使用的那些站点并没有很好地检测/处理无效的UTF8字符串

这个base-64字符串中的数据可能是使用不同的编码从字符串转换而来的。或者,也许它最初根本不是一根弦。并非所有二进制有效负载都具有干净的字符串表示形式。坦率地说,这就是为什么我们首先使用base-64表示法,以得到不是字符串的数据块的文本表示法


如果您提供有关此base-64字符串中包含的数据源的更多信息,我们可能会进一步向您提供建议。

这与您之前的问题基本相同,我的建议与此相同:不要将数据转换为字符串。–如果你不得不这样做(出于某种神秘的原因),那么选择一种不同的编码方式(正如你之前问题的答案中所述)。显然,这些网站用ISO拉丁语编码解释数据,我想知道OP从讨论和他之前问题的答案中学到了什么:(@MartinR-也许。也许他们根本没有做错误检测(因为如果显式选择UTF8,第一个站点仍然会显示一个字符串)坦率地说,当我注意到他们没有检测到UTF8字符串表示错误时,我对这些网站失去了所有信心,这就是为什么我回到UTF8的定义来确认。当然,你是完全正确的。-如果你用
.isoLatin1
转换给定的数据,那么结果就是
uöHjoÖ¾@'ÖÖ
,这就是什么t OP期望。但我们在他之前的问题中与OP讨论了所有这些,我很想把它作为一个重复来结束…@MartinR-Fine。但我仍然不会假设这是原始字符串,他们显式地得到了拉丁-1表示,然后将其转换为base-64字符串表示。更可能的是,o原始有效载荷根本不是字符串,OP在试图将其表示为字符串时一直被误导。但我们只是猜测,直到OP告诉我们base-64编码有效载荷的来源。这正是我的意思(可能我表达得很糟糕)。在上一个问题中,它是AES密钥 75f61c48 6a6f06ac b3be4017 91d6c70c