c#の検出xmlエンコーディングからバイト配列?
-
06-09-2019 - |
質問
大学などが関わっていて、バイト配列の場合は、知っていそxml serilizedオブジェクトのバイト配列、本当にありがとうにエンコードしているか確認してください。
Imいdeserilizeまで保存するまでは、xmlの分野にsqlサーバーの...ながらやっていく必要があるとして文字列?
解決
あなたは最初の40っぽいバイト 1 で見ることができます。彼らは、<全角> はドキュメント宣言を含まなければならない(それを想定し、<全角>はのドキュメント宣言)エンコーディングを含める必要がありますいずれかのまたは<を/全角>は、あなたがそれを取ることができるが、UTF-8ですかUTF-16、あなたは<?xml
部分を理解してきた方法から明らかである必要があります。 (ただ、両方のパターンを確認してください。)
現実的に、あなたは今までにUTF-8またはUTF-16以外のものを得ることができます期待していますか?そうでない場合、あなたはそれらの両方の開始時に取得したパターンをチェックすることができ、それはどちらかのパターンに従わない場合に例外をスローします。あなたが別の試みを作りたい場合は別の方法として、あなたは常にそれを再エンコードし、あなたが戻って同じバイトを取得するかどうかを確認し、UTF-8として文書を解読しようとすることができます。それは理想的ではないが、それだけでうまくいくかもしれない。
私はこれを行うためのより厳密な方法があると確信しているが、彼らは細心の注意である可能性が高いです:)
<時間>1 かなり可能性がこれよりも少ないです。私は、UTF-16で40バイトである、20文字は十分なはず把握ます。
他のヒント
この質問をhref="https://stackoverflow.com/questions/637855/how-to-best-detect-encoding-in-xml-file"> には、これを解決することができバイト配列上のストリームを使用します。その後、バイトレベルでいじる必要はありません。このように:
Encoding encoding;
using (var stream = new MemoryStream(bytes))
{
using (var xmlreader = new XmlTextReader(stream))
{
xmlreader.MoveToContent();
encoding = xmlreader.Encoding;
}
}
最初の2つのまたは3バイトは、ストリームがUTF-8であるかどうかを伝えることができますバイトオーダーマーク(BOM)であってもよいし、ユニコード・littleEndianのまたはUnicode-BIGENDIANます。
UTF-8 BOMは0xEFという0xBB 0xbfのです ユニコード-BIGENDIANは0xFEの0xFFであります ユニコード-LittleEndiaonが0xFF 0xFEのです。
これらのどれもが存在しない場合、あなたは(何のホワイトスペースは、XML宣言をpreceedないかもしれないことを標準に最も近代的なXML生成スティックに注意してください)<?xml
をテストするためにASCIIを使用することができます。
ASCIIは?>
まで使用されています。
エンコーディングが存在しないか、<?xml
の宣言が存在しない場合、あなたはUTF-8を想定することができます。
の W3C XML仕様の一部 に関するあらゆる側面を含んでいますの符号化バイト文字列になります。
最初のチェックしUnicodeのバイト順マーク
BOMは別の文字;もの:
文字 U+FEFF, ひの字のファイルは、符号化された使用に適切なエンコーディング方式:
00 00 FE FF
: UCS-4のビッグエンディアン形式の機(1234)FF FE 00 00
: UCS-4、リトルエンディアンマシン(4321)00 00 FF FE
: UCS-4では、異常なオクテット(2143)FE FF 00 00
: UCS-4では、異常なオクテット(3412)FE FF ## ##
: UTF-16では、"ビッグエンディアンFF FE ## ##
: UTF-16、リトルエンディアンEF BB BF
: UTF-8
場所 ## ##
できるものを除き、存在していたと考えられているゼロ
なので最初にチェックをinitalバイトのフェースの通称です。ばくに戻る コードページの識別子
UInt32 GuessEncoding(byte[] XmlString)
{
if BytesEqual(XmlString, [00, 00, $fe, $ff]) return 12001; //"utf-32BE" - Unicode UTF-32, big endian byte order
if BytesEqual(XmlString, [$ff, $fe, 00, 00]) return 1200; //"utf-32" - Unicode UTF-32, little endian byte order
if BytesEqual(XmlString, [$fe, $ff, 00, 00]) throw new Exception("Nobody supports 2143 UCS-4");
if BytesEqual(XmlString, [$fe, $ff, 00, 00]) throw new Exception("Nobody supports 3412 UCS-4");
if BytesEqual(XmlString, [$fe, $ff])
{
if (XmlString[2] <> 0) && (XmlString[3] <> 0)
return 1201; //"unicodeFFFE" - Unicode UTF-16, big endian byte order
}
if BytesEqual(XmlString, [$ff, $fe])
{
if (XmlString[2] <> 0) && (XmlString[3] <> 0)
return 1200; //"utf-16" - Unicode UTF-16, little endian byte order
}
if BytesEqual(XmlString, [$ef, $bb, $bf]) return 65001; //"utf-8" - Unicode (UTF-8)
もう <?xml
場合は、XMLドキュメントにはないバイト順マーク、文字、そしてきみのための最初の文字の全てのXML文書が必要:
<?xml
でも知る
<
は#x0000003C?
は#x0000003F
としての最初のバイト:
00 00 00 3C
: UCS-4のビッグエンディアン形式の機(1234)3C 00 00 00
: UCS-4、リトルエンディアンマシン(4321)00 00 3C 00
: UCS-4では、異常なオクテット(2143)00 3C 00 00
: UCS-4では、異常なオクテット(3412)00 3C 00 3F
: UTF-16では、"ビッグエンディアン3C 00 3F 00
: UTF-16、リトルエンディアン3C 3F 78 6D
: UTF-84C 6F A7 94
: 一部の趣EBCDIC
今後の追加より当社コード:
if BytesEqual(XmlString, [00, 00, 00, $3C]) return 12001; //"utf-32BE" - Unicode UTF-32, big endian byte order
if BytesEqual(XmlString, [$3C, 00, 00, 00]) return 1200; //"utf-32" - Unicode UTF-32, little endian byte order
if BytesEqual(XmlString, [00, 00, $3C, 00]) throw new Exception("Nobody supports 2143 UCS-4");
if BytesEqual(XmlString, [00, $3C, 00, 00]) throw new Exception("Nobody supports 3412 UCS-4");
if BytesEqual(XmlString, [00, $3C, 00, $3F]) return return 1201; //"unicodeFFFE" - Unicode UTF-16, big endian byte order
if BytesEqual(XmlString, [$3C, 00, $3F, 00]) return 1200; //"utf-16" - Unicode UTF-16, little endian byte order
if BytesEqual(XmlString, [$3C, $3F, $78, $6D]) return 65001; //"utf-8" - Unicode (UTF-8)
if BytesEqual(XmlString, [$4C, $6F, $A7, $94])
{
//Some variant of EBCDIC, e.g.:
//20273 IBM273 IBM EBCDIC Germany
//20277 IBM277 IBM EBCDIC Denmark-Norway
//20278 IBM278 IBM EBCDIC Finland-Sweden
//20280 IBM280 IBM EBCDIC Italy
//20284 IBM284 IBM EBCDIC Latin America-Spain
//20285 IBM285 IBM EBCDIC United Kingdom
//20290 IBM290 IBM EBCDIC Japanese Katakana Extended
//20297 IBM297 IBM EBCDIC France
//20420 IBM420 IBM EBCDIC Arabic
//20423 IBM423 IBM EBCDIC Greek
//20424 IBM424 IBM EBCDIC Hebrew
//20833 x-EBCDIC-KoreanExtended IBM EBCDIC Korean Extended
//20838 IBM-Thai IBM EBCDIC Thai
//20866 koi8-r Russian (KOI8-R); Cyrillic (KOI8-R)
//20871 IBM871 IBM EBCDIC Icelandic
//20880 IBM880 IBM EBCDIC Cyrillic Russian
//20905 IBM905 IBM EBCDIC Turkish
//20924 IBM00924 IBM EBCDIC Latin 1/Open System (1047 + Euro symbol)
throw new Exception("We don't support EBCDIC. Sorry");
}
//Otherwise assume UTF-8, and fail to decode it anyway
return 65001; //"utf-8" - Unicode (UTF-8)
//Any code is in the public domain. No attribution required.
}