亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

PHP 的 utf8_decode 和 C# 的 Encoding.UTF8.GetString

PHP 的 utf8_decode 和 C# 的 Encoding.UTF8.GetString

PHP
MMTTMM 2023-04-21 13:37:45
我有這個 PHP 代碼,它使用 utf8_decode() 在 UTF-8 字符串中轉換兩個字節數組(一個有 32 個字節,另一個有 70 個字節):$bytes32 = [144, 204, 205, 119, 77, 176, 172, 140, 110, 162, 222, 255, 14, 38, 252, 82, 118, 138, 130, 124, 145, 199, 55, 162, 224, 80, 102, 141, 140, 57, 194, 36];$string32 = implode(array_map("chr", $bytes32));$string32Utf8 = utf8_decode($string32);$bytes70 = [239, 191, 189, 239, 191, 189, 239, 191, 189, 119, 77, 239, 191, 189, 239, 191, 189, 239, 191, 189, 110, 239, 191, 189, 239, 191, 189, 239, 191, 189, 14, 38, 239, 191, 189, 82, 118, 239, 191, 189, 239, 191, 189, 124, 239, 191, 189, 239, 191, 189, 55, 239, 191, 189, 239, 191, 189, 80, 102, 239, 191, 189, 239, 191, 189, 57, 239, 191, 189, 36];$string70 = implode(array_map("chr", $bytes70));$string70Utf8 = utf8_decode($string70);echo '$string32Utf8: ' . $string32Utf8; // echoes ???wM???n??&?Rv??|??7??Pf??9?$echo '$string70Utf8: ' . $string70Utf8; // echoes ???wM???n???&?Rv??|??7??Pf??9?$echo '$string32Utf8 === $string70Utf8: ' . json_encode($string32Utf8 ===  $string70Utf8); // echoes false然后我有這個 C# 代碼,它使用 Encoding.UTF8.GetString() 做同樣的事情:byte[] bytes32 = new byte[] { 144, 204, 205, 119, 77, 176, 172, 140, 110, 162, 222, 255, 14, 38, 252, 82, 118, 138, 130, 124, 145, 199, 55, 162, 224, 80, 102, 141, 140, 57, 194, 36 };string string32Utf8 = Encoding.UTF8.GetString(bytes32);byte[] bytes70 = new byte[] { 239, 191, 189, 239, 191, 189, 239, 191, 189, 119, 77, 239, 191, 189, 239, 191, 189, 239, 191, 189, 110, 239, 191, 189, 239, 191, 189, 239, 191, 189, 14, 38, 239, 191, 189, 82, 118, 239, 191, 189, 239, 191, 189, 124, 239, 191, 189, 239, 191, 189, 55, 239, 191, 189, 239, 191, 189, 80, 102, 239, 191, 189, 239, 191, 189, 57, 239, 191, 189, 36 };string string70Utf8 = Encoding.UTF8.GetString(bytes70);首先,在 C# 中,兩個字節數組在轉換后產生相同的字符串,這與 PHP 不同。其次,與 PHP 相比,C# 中的字符串有所不同。PHP 中是否有一個函數在給定相同輸入的情況下實際上會返回與 C# 的 Encoding.UTF8.GetString() 相同的輸出?或者是否有我遺漏的東西實際上導致了 C# 和 PHP 之間的不同輸出?
查看完整描述

1 回答

?
動漫人物

TA貢獻1815條經驗 獲得超10個贊

您示例中的字節數組不是有效的 UTF-8。基本上,如果您在 C# 輸出中看到 ?? 符號,則表示Encoding.UTF8.GetString()使用替換字符來表示無法轉換為輸出字符的編碼輸入字節序列。

但是,您仍然可以在 PHP 中重現完全相同的行為Encoding.UTF8.GetString()

$bytes32 = [144, 204, 205, 119, 77, 176, 172, 140, 110, 162, 222, 255, 14, 38, 252, 82, 118, 138, 130, 124, 145, 199, 55, 162, 224, 80, 102, 141, 140, 57, 194, 36];

$string32 = \pack('C*', ...$bytes32);

$string32Utf8 = \mb_convert_encoding($string32, 'ASCII', 'UTF-8');


$bytes70 = [239, 191, 189, 239, 191, 189, 239, 191, 189, 119, 77, 239, 191, 189, 239, 191, 189, 239, 191, 189, 110, 239, 191, 189, 239, 191, 189, 239, 191, 189, 14, 38, 239, 191, 189, 82, 118, 239, 191, 189, 239, 191, 189, 124, 239, 191, 189, 239, 191, 189, 55, 239, 191, 189, 239, 191, 189, 80, 102, 239, 191, 189, 239, 191, 189, 57, 239, 191, 189, 36];

$string70 = \pack('C*', ...$bytes70);

$string70Utf8 = \mb_convert_encoding($string70, 'ASCII', 'UTF-8');


\var_dump($string32Utf8, $string70Utf8, $string32Utf8 === $string70Utf8);

我做的不同的事情:

  1. 由于 byte array 表示UTF-8 string,我們不能使用chr將其轉換為二進制字符串。如chr函數文檔中所述:

    此函數不知道任何字符串編碼,特別是不能傳遞 Unicode 代碼點值以生成多字節編碼(如 UTF-8 或 UTF-16)的字符串。

    pack另一方面,函數可以處理各種類型的二進制數據格式。\pack('C*', ...$bytes32)意味著字節數組將被視為一系列無符號字符并打包成二進制字符串。

  2. utf8_decode函數有一個非常混亂的名字;它應該被命名為類似的東西,utf8_to_iso88591因為這正是它的作用:

    將包含以 UTF-8 編碼的 ISO-8859-1 字符的字符串轉換為單字節 ISO-8859-1

    如果我們想復制Encoding.UTF8.GetString()示例,我們真正需要做的是將 UTF-8 編碼的二進制字符串轉換為 ASCII。你可以使用mb_convert_encoding函數來做到這一點,就像這樣:mb_convert_encoding($utf8String, 'ASCII', 'UTF-8')

希望這些評論會有所幫助!


查看完整回答
反對 回復 2023-04-21
  • 1 回答
  • 0 關注
  • 173 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號