将 base64 编码的字符串转换为 swift 中的普通字符串 3
Convert base64-encoded string to normal string in swift 3
我想转换以下 base64 编码的 String
in Swift 3:
dfYcSGpvBqyzvkAXkdbHDA==
与其等价的String
:
uöHjo¬³¾@‘ÖÇ
以下网站做得很好:
http://www.motobit.com/util/base64-decoder-encoder.asp
http://www.utilities-online.info/base64/#.WG-FwrFh2Rs
PHP 的函数 base64_decode
也是如此。这个函数的documentation表示:
Returns FALSE if input contains character from outside the base64
alphabet.
但我无法在 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 参数值。为此,我使用 this lib。
他给了我十六进制格式的 AES 密钥(我在 中提到)和 base64 中的 iv(上面给出),他指示我在使用前解码这个 base64 密钥,因为他也在他的 [=51 中做同样的事情=] 代码。这是他的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 );
}
我刚看到这段 PHP 代码,想知道为什么他不使用 $iv 作为 mcrypt_decrypt
函数的最后一个参数!!会更新你的。但是问题还是一样,PHP 函数 base64_decode
不会 return FALSE
对于上面的 base64 字符串!
我自己通过终端命令测试了这个功能:php test.php
。这里 test.php 包含以下代码:
<?php
$iv = base64_decode ( "dfYcSGpvBqyzvkAXkdbHDA==" );
echo $iv;
?>
输出为:u?Hjo???@???
查看您修改后的问题,您正在尝试使用此 base-64 字符串,并将其用作 AES 算法中的 iv
。我能理解您为什么想知道如何将结果 Data
转换为 String
,但您不应该那样做。是的,有一个 AES
的演绎版,它期望 iv
作为一个字符串。但还有另一种演绎形式需要 Array<UInt8>
。所以,就像 MartinR 在 中所说的那样,改为构建一个 UInt8
的数组,如下所示:
let iv = Array(Data(base64Encoded: "dfYcSGpvBqyzvkAXkdbHDA==")!)
结果 iv
是 Array<UInt8>
(也称为 [UInt8]
)。您可以将其与 AES
函数一起使用。
我最初关于将 Data
对象转换为 UTF8 字符串的讨论如下。但关键信息是您不应该尝试这样做。只需构建您的 UInt8
数组并将其与您的库的 AES
函数一起使用。
查看您的其他问题 (),您在评论中透露您正在处理 AES 密钥。我怀疑我们在这里处理类似的问题(虽然那是 32 字节的数据,而这里我们有 16 字节)。
最重要的是,我建议您完全放弃此 "how to I get a string representation of the data captured in this base-64 string" 询问行。如果它是加密密钥(或某种令牌或其他),请不要试图将其表示为字符串。 (这是 base-64 的 存在理由,用于创建非字符串数据的可传输字符串表示。)
我建议您退后一步,描述您要解决的更广泛的问题。停止尝试从这些二进制有效负载中创建字符串。在您的代码片段中,您成功地从 base-64 字符串创建了一个 Data
。我认为真正的问题不是 "how do I now get a string from that?",而是 "what do I do this Data
?"
如果没有关于您从何处获得这些数据及其用途的更多背景信息,我们无法回答该问题。
顺便说一句,我对你的问题的原始回答如下。
问题是 base-64 字符串转换为 16 字节的数据,其十六进制表示为
75f61c48 6a6f06ac b3be4017 91d6c70c
但该负载不是有效的 UTF8 字符串。第三个字节,1c
与UTF8字符串不一致。如果你看definition of UTF8,它说如果一个字节在f6
-fb
范围内,也就是第二个字节,那么这个字符由那个和后面两个组成字节,两者都应该在21
–7e
或a0
–ff
范围内,而1c
不是。
所以,这根本不是有效的 UTF8 字符串。很明显,您使用的那些网站并不优雅 detecting/handling 无效的 UTF8 字符串。
可能此 base-64 字符串中的数据是从使用不同编码的字符串转换而来的。或者,也许它本来就不是字符串。并非所有二进制有效负载都具有干净的字符串表示形式。坦率地说,这就是我们首先使用 base-64 表示的原因,以提出不是字符串的数据块的文本表示。
如果您提供有关此 base-64 字符串中包含的数据源的更多信息,我们也许可以为您提供进一步的建议。
我想转换以下 base64 编码的 String
in Swift 3:
dfYcSGpvBqyzvkAXkdbHDA==
与其等价的String
:
uöHjo¬³¾@‘ÖÇ
以下网站做得很好:
http://www.motobit.com/util/base64-decoder-encoder.asp
http://www.utilities-online.info/base64/#.WG-FwrFh2Rs
PHP 的函数 base64_decode
也是如此。这个函数的documentation表示:
Returns FALSE if input contains character from outside the base64 alphabet.
但我无法在 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 参数值。为此,我使用 this lib。
他给了我十六进制格式的 AES 密钥(我在
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 );
}
我刚看到这段 PHP 代码,想知道为什么他不使用 $iv 作为 mcrypt_decrypt
函数的最后一个参数!!会更新你的。但是问题还是一样,PHP 函数 base64_decode
不会 return FALSE
对于上面的 base64 字符串!
我自己通过终端命令测试了这个功能:php test.php
。这里 test.php 包含以下代码:
<?php
$iv = base64_decode ( "dfYcSGpvBqyzvkAXkdbHDA==" );
echo $iv;
?>
输出为:u?Hjo???@???
查看您修改后的问题,您正在尝试使用此 base-64 字符串,并将其用作 AES 算法中的 iv
。我能理解您为什么想知道如何将结果 Data
转换为 String
,但您不应该那样做。是的,有一个 AES
的演绎版,它期望 iv
作为一个字符串。但还有另一种演绎形式需要 Array<UInt8>
。所以,就像 MartinR 在 UInt8
的数组,如下所示:
let iv = Array(Data(base64Encoded: "dfYcSGpvBqyzvkAXkdbHDA==")!)
结果 iv
是 Array<UInt8>
(也称为 [UInt8]
)。您可以将其与 AES
函数一起使用。
我最初关于将 Data
对象转换为 UTF8 字符串的讨论如下。但关键信息是您不应该尝试这样做。只需构建您的 UInt8
数组并将其与您的库的 AES
函数一起使用。
查看您的其他问题 (
最重要的是,我建议您完全放弃此 "how to I get a string representation of the data captured in this base-64 string" 询问行。如果它是加密密钥(或某种令牌或其他),请不要试图将其表示为字符串。 (这是 base-64 的 存在理由,用于创建非字符串数据的可传输字符串表示。)
我建议您退后一步,描述您要解决的更广泛的问题。停止尝试从这些二进制有效负载中创建字符串。在您的代码片段中,您成功地从 base-64 字符串创建了一个 Data
。我认为真正的问题不是 "how do I now get a string from that?",而是 "what do I do this Data
?"
如果没有关于您从何处获得这些数据及其用途的更多背景信息,我们无法回答该问题。
顺便说一句,我对你的问题的原始回答如下。
问题是 base-64 字符串转换为 16 字节的数据,其十六进制表示为
75f61c48 6a6f06ac b3be4017 91d6c70c
但该负载不是有效的 UTF8 字符串。第三个字节,1c
与UTF8字符串不一致。如果你看definition of UTF8,它说如果一个字节在f6
-fb
范围内,也就是第二个字节,那么这个字符由那个和后面两个组成字节,两者都应该在21
–7e
或a0
–ff
范围内,而1c
不是。
所以,这根本不是有效的 UTF8 字符串。很明显,您使用的那些网站并不优雅 detecting/handling 无效的 UTF8 字符串。
可能此 base-64 字符串中的数据是从使用不同编码的字符串转换而来的。或者,也许它本来就不是字符串。并非所有二进制有效负载都具有干净的字符串表示形式。坦率地说,这就是我们首先使用 base-64 表示的原因,以提出不是字符串的数据块的文本表示。
如果您提供有关此 base-64 字符串中包含的数据源的更多信息,我们也许可以为您提供进一步的建议。