特定のエンコーディングを手動で指定せずに、.NET (C#) でastring
を aに変換するにはどうすればよいですか?byte[]
文字列を暗号化していきます。変換せずに暗号化できますが、ここでエンコーディングが機能する理由を知りたいです。
また、エンコーディングを考慮する必要があるのはなぜですか? 文字列が格納されているバイト数を簡単に取得できませんか? 文字エンコーディングに依存するのはなぜですか?
特定のエンコーディングを手動で指定せずに、.NET (C#) でastring
を aに変換するにはどうすればよいですか?byte[]
文字列を暗号化していきます。変換せずに暗号化できますが、ここでエンコーディングが機能する理由を知りたいです。
また、エンコーディングを考慮する必要があるのはなぜですか? 文字列が格納されているバイト数を簡単に取得できませんか? 文字エンコーディングに依存するのはなぜですか?
ここでの回答とは対照的に、バイトを解釈する必要がない場合は、エンコードについて心配する必要はありません!
あなたが述べたように、あなたの目標は、単に「文字列が格納されているバイト数を取得する」ことです。
(もちろん、バイトから文字列を再構築できるようにするためです。)
これらの目標のために、エンコーディングが必要だと人々が言い続ける理由が正直にわかりません。このためのエンコーディングについて心配する必要はありません。
代わりにこれを行うだけです:
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
// Do NOT use on arbitrary bytes; only use on GetBytes's output on the SAME system
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
あなたのプログラム (または他のプログラム) が何らかの方法でバイトを解釈しようとしない限り、それはあなたが意図していることを明らかに言及していませんが、このアプローチには何の問題もありません! エンコーディングについて心配すると、本当の理由もなく生活が複雑になります。
このアプローチの追加の利点: データを取得して元の文字列を再構築できるため、文字列に無効な文字が含まれていても問題ありません。
bytes を見ているだけなので、同じようにエンコードおよびデコードされます。
ただし、特定のエンコーディングを使用すると、無効な文字のエンコード/デコードに問題が発生する可能性があります。
文字列のエンコーディング ( ASCII、UTF-8など) によって異なります。
例えば:
byte[] b1 = System.Text.Encoding.UTF8.GetBytes (myString);
byte[] b2 = System.Text.Encoding.ASCII.GetBytes (myString);
エンコーディングが重要な理由の小さなサンプル:
string pi = "\u03a0";
byte[] ascii = System.Text.Encoding.ASCII.GetBytes (pi);
byte[] utf8 = System.Text.Encoding.UTF8.GetBytes (pi);
Console.WriteLine (ascii.Length); //Will print 1
Console.WriteLine (utf8.Length); //Will print 2
Console.WriteLine (System.Text.Encoding.ASCII.GetString (ascii)); //Will print '?'
ASCII には、特殊文字を処理する機能が備わっていません。
内部的に、.NET フレームワークは文字列を表すためにUTF-16を使用するため、単に .NET が使用する正確なバイト数を取得したい場合は、System.Text.Encoding.Unicode.GetBytes (...)
.
詳細については、.NET Framework の文字エンコード(MSDN) を参照してください。
受け入れられた答えは非常に複雑です。これには、含まれている .NET クラスを使用します。
const string data = "A string with international characters: Norwegian: ÆØÅæøå, Chinese: 喂 谢谢";
var bytes = System.Text.Encoding.UTF8.GetBytes(data);
var decoded = System.Text.Encoding.UTF8.GetString(bytes);
必要がない場合は、車輪を再発明しないでください...
BinaryFormatter bf = new BinaryFormatter();
byte[] bytes;
MemoryStream ms = new MemoryStream();
string orig = "喂 Hello 谢谢 Thank You";
bf.Serialize(ms, orig);
ms.Seek(0, 0);
bytes = ms.ToArray();
MessageBox.Show("Original bytes Length: " + bytes.Length.ToString());
MessageBox.Show("Original string Length: " + orig.Length.ToString());
for (int i = 0; i < bytes.Length; ++i) bytes[i] ^= 168; // pseudo encrypt
for (int i = 0; i < bytes.Length; ++i) bytes[i] ^= 168; // pseudo decrypt
BinaryFormatter bfx = new BinaryFormatter();
MemoryStream msx = new MemoryStream();
msx.Write(bytes, 0, bytes.Length);
msx.Seek(0, 0);
string sx = (string)bfx.Deserialize(msx);
MessageBox.Show("Still intact :" + sx);
MessageBox.Show("Deserialize string Length(still intact): "
+ sx.Length.ToString());
BinaryFormatter bfy = new BinaryFormatter();
MemoryStream msy = new MemoryStream();
bfy.Serialize(msy, sx);
msy.Seek(0, 0);
byte[] bytesy = msy.ToArray();
MessageBox.Show("Deserialize bytes Length(still intact): "
+ bytesy.Length.ToString());
1 文字は 1 バイト以上(約 6 バイトまで) で表すことができ、エンコーディングが異なればこれらのバイトの扱いも異なるため、エンコーディングを考慮する必要があります。
Joel はこれについて次のように投稿しています。
すべてのソフトウェア開発者が絶対に、積極的に Unicode と文字セットについて知っておく必要がある絶対最小値 (言い訳はありません!)
これはよくある質問です。質問の作成者が何を求めているのか、またそれが最も一般的なニーズとは異なることを理解することが重要です。必要のないところでのコードの誤用を思いとどまらせるために、私は後者を先に回答しました。
すべての文字列には文字セットとエンコーディングがあります。System.String
オブジェクトを配列に変換しSystem.Byte
ても、文字セットとエンコーディングは保持されます。ほとんどの用途では、必要な文字セットとエンコーディングがわかっているため、.NET を使用すると "変換してコピー" することが簡単になります。Encoding
適切なクラスを選択するだけです。
// using System.Text;
Encoding.UTF8.GetBytes(".NET String to byte array")
変換では、ターゲットの文字セットまたはエンコーディングがソース内の文字をサポートしていない場合を処理する必要がある場合があります。いくつかの選択肢があります: 例外、置換、またはスキップ。デフォルトのポリシーは、'?' に置き換えることです。
// using System.Text;
var text = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes("You win €100"));
// -> "You win ?100"
明らかに、変換は必ずしもロスレスではありません!
注:System.String
ソース文字セットは Unicode です。
唯一紛らわしいのは、.NET がその文字セットの 1 つの特定のエンコーディングの名前として文字セットの名前を使用することです。Encoding.Unicode
と呼ばれるべきEncoding.UTF16
です。
ほとんどの用途はこれで終わりです。それが必要な場合は、ここで読むのをやめてください。エンコーディングとは何かを理解していない場合は、楽しいJoel Spolsky の記事を参照してください。
ここで、著者は、「すべての文字列はバイトの配列として格納されますよね?なぜ単純にそれらのバイトを取得できないのでしょうか?」と尋ねています。
彼は改宗を望んでいません。
C#仕様から:
C# での文字と文字列の処理では、Unicode エンコーディングが使用されます。char 型は UTF-16 コード単位を表し、string 型は一連の UTF-16 コード単位を表します。
したがって、null 変換 (つまり、UTF-16 から UTF-16 へ) を要求すると、望ましい結果が得られることがわかっています。
Encoding.Unicode.GetBytes(".NET String to byte array")
しかし、エンコーディングについての言及を避けるために、別の方法で行う必要があります。中間データ型が許容される場合、これには概念的なショートカットがあります。
".NET String to byte array".ToCharArray()
それは目的のデータ型を取得しませんが、Mehrdad の回答は、 BlockCopyを使用してこの Char 配列を Byte 配列に変換する方法を示しています。ただし、これは文字列を 2 回コピーします。また、エンコーディング固有のコードである datatype も明示的に使用しますSystem.Char
。
String が格納されている実際のバイトを取得する唯一の方法は、ポインターを使用することです。このfixed
ステートメントでは、値のアドレスを取得できます。C# 仕様から:
[For] 文字列型の式 ... イニシャライザは、文字列の最初の文字のアドレスを計算します。
これを行うために、コンパイラは、文字列オブジェクトの他の部分を でスキップするコードを記述しますRuntimeHelpers.OffsetToStringData
。したがって、生のバイトを取得するには、文字列へのポインターを作成し、必要なバイト数をコピーするだけです。
// using System.Runtime.InteropServices
unsafe byte[] GetRawBytes(String s)
{
if (s == null) return null;
var codeunitCount = s.Length;
/* We know that String is a sequence of UTF-16 codeunits
and such codeunits are 2 bytes */
var byteCount = codeunitCount * 2;
var bytes = new byte[byteCount];
fixed(void* pRaw = s)
{
Marshal.Copy((IntPtr)pRaw, bytes, 0, byteCount);
}
return bytes;
}
@CodesInChaos が指摘したように、結果はマシンのエンディアンに依存します。しかし、質問者はそれには関心がありません。
あなたの質問の最初の部分 (バイトを取得する方法) は、他の人によって既に回答されています:System.Text.Encoding
名前空間を見てください。
フォローアップの質問にお答えします。なぜエンコーディングを選択する必要があるのですか? 文字列クラス自体からそれを取得できないのはなぜですか?
答えは 2 つの部分にあります。
まず第一に、文字列クラスによって内部的に使用されるバイトは問題ではありません。問題があると仮定すると、バグが発生する可能性があります。
プログラムが完全に .Net ワールド内にある場合は、ネットワーク経由でデータを送信している場合でも、文字列のバイト配列の取得について心配する必要はまったくありません。代わりに、.Net Serialization を使用して、データの送信について心配してください。実際のバイト数について心配する必要はもうありません。シリアライゼーション フォーマッタが自動的に処理してくれます。
一方、これらのバイトを、.Net シリアル化ストリームからデータを取得できるとは限らない場所に送信している場合はどうなるでしょうか。この場合、明らかにこの外部システムが気にするので、エンコーディングについて心配する必要があります。繰り返しますが、文字列で使用される内部バイトは問題ではありません。受信側でこのエンコーディングについて明示できるように、エンコーディングを選択する必要があります。.Net で内部的に使用されるエンコーディングと同じ場合でも。
この場合、可能な場合は文字列変数によってメモリに格納された実際のバイトを使用することをお勧めします。これにより、バイト ストリームを作成する作業を節約できる可能性があります。ただし、出力が相手側で確実に理解されるようにすることと比較して重要ではなく、エンコードを明示的に行う必要があることを保証することは重要ではありません。さらに、内部バイトを本当に一致させたい場合は、Unicode
エンコーディングを選択するだけで、パフォーマンスを節約できます。
これにより、2番目の部分に進みます...Unicode
エンコーディングを選択すると、.Netに基になるバイトを使用するように指示されます。このエンコーディングを選択する必要があるのは、新しい Unicode-Plus が出てきたときに、.Net ランタイムが、プログラムを壊すことなく、この新しい、より優れたエンコーディング モデルを自由に使用できるようにする必要があるためです。しかし、今のところ (そして近い将来)、Unicode エンコーディングを選択するだけで、必要なものが得られます。
文字列を再書き込みして配線する必要があることを理解することも重要です。これには、一致する encoding を使用する場合でも、ビットパターンの少なくとも一部の変換が含まれます。コンピューターは、ビッグ エンディアンとリトル エンディアン、ネットワーク バイト オーダー、パケット化、セッション情報などを考慮する必要があります。
Mehrdrad の健全な答えが機能することを示すために、彼のアプローチはペアになっていないサロゲート文字を永続化することさえできます(その多くは私の答えに反対していましたが、誰もが同じように罪を犯しています。たとえば、これらの文字は単に上位サロゲート文字を value に置き換えるだけです) :System.Text.Encoding.UTF8.GetBytes
System.Text.Encoding.Unicode.GetBytes
d800
fffd
using System;
class Program
{
static void Main(string[] args)
{
string t = "爱虫";
string s = "Test\ud800Test";
byte[] dumpToBytes = GetBytes(s);
string getItBack = GetString(dumpToBytes);
foreach (char item in getItBack)
{
Console.WriteLine("{0} {1}", item, ((ushort)item).ToString("x"));
}
}
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
}
出力:
T 54
e 65
s 73
t 74
? d800
T 54
e 65
s 73
t 74
System.Text.Encoding.UTF8.GetBytesまたはSystem.Text.Encoding.Unicode.GetBytesでそれを試してみてください。それらは単に上位サロゲート文字を値fffdに置き換えるだけです
この質問に動きがあるたびに、ペアになっていないサロゲート文字が含まれていても文字列を保持できるシリアライザー (Microsoft またはサードパーティ コンポーネント) を考えています。私は時々これをグーグルで検索します:シリアライゼーションのペアになっていないサロゲート文字 .NET。これで眠れなくなることはありませんが、私の回答に欠陥があるとコメントする人が時々いるのはちょっと面倒です。
くそー、Microsoft はSystem.Buffer.BlockCopy
その中で使用する必要がありましたBinaryFormatter
ツ</p>
谢谢!</p>
これを試してみてください。コードを大幅に減らします。
System.Text.Encoding.UTF8.GetBytes("TEST String");
さて、私はすべての回答を読みましたが、それらはエンコーディングの使用に関するものか、対になっていないサロゲートを削除するシリアライゼーションに関するものでした。
たとえば、文字列が、パスワード ハッシュなどを格納するバイト配列から構築されたSQL Serverから取得された場合、これは問題です。そこから何かをドロップすると、無効なハッシュが格納されます。それを XML に格納する場合は、そのままにしておく必要があります (XML ライターは、ペアになっていないサロゲートを見つけた場合に例外をドロップするため)。
だから私はそのような場合にバイト配列のBase64エンコーディングを使用しますが、ちょっと、インターネットではこれに対するC#での解決策は1つしかなく、バグがあり、1つの方法しかないので、バグを修正して返信しました手順。未来の Google 社員の皆さん:
public static byte[] StringToBytes(string str)
{
byte[] data = new byte[str.Length * 2];
for (int i = 0; i < str.Length; ++i)
{
char ch = str[i];
data[i * 2] = (byte)(ch & 0xFF);
data[i * 2 + 1] = (byte)((ch & 0xFF00) >> 8);
}
return data;
}
public static string StringFromBytes(byte[] arr)
{
char[] ch = new char[arr.Length / 2];
for (int i = 0; i < ch.Length; ++i)
{
ch[i] = (char)((int)arr[i * 2] + (((int)arr[i * 2 + 1]) << 8));
}
return new String(ch);
}
また、エンコーディングを考慮する必要がある理由を説明してください。文字列が格納されているバイト数を簡単に取得できませんか? このエンコーディングへの依存はなぜですか?!!!
「文字列のバイト」などというものはないからです。
文字列 (より一般的にはテキスト) は、文字、数字、その他の記号などの文字で構成されています。それで全部です。しかし、コンピュータは文字について何も知りません。バイトのみを処理できます。したがって、コンピューターを使用してテキストを保存または送信する場合は、文字をバイトに変換する必要があります。どうやってそれをしますか?ここでエンコーディングが登場します。
エンコーディングは、論理文字を物理バイトに変換するための規則に他なりません。最も単純で最もよく知られているエンコーディングは ASCII であり、英語で書く場合はこれで十分です。他の言語の場合は、より完全なエンコーディングが必要になります。最近では Unicode フレーバーのいずれかが最も安全な選択です。
要するに、「エンコーディングを使用せずに文字列のバイトを取得する」ことは、「言語を使用せずにテキストを書く」ことと同じくらい不可能です。
ところで、私はあなた (そして誰でも) にこの小さな知恵を読むことを強くお勧めします:すべてのソフトウェア開発者が絶対に、積極的に Unicode と文字セットについて知っておく必要がある絶対最小値 (言い訳はありません!)
string
a をbyte
配列に変換する C# :
public static byte[] StrToByteArray(string str)
{
System.Text.UTF8Encoding encoding=new System.Text.UTF8Encoding();
return encoding.GetBytes(str);
}
byte[] strToByteArray(string str)
{
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
return enc.GetBytes(str);
}
文字列とバイト配列の間の変換には、次のコードを使用できます。
string s = "Hello World";
// String to Byte[]
byte[] byte1 = System.Text.Encoding.Default.GetBytes(s);
// OR
byte[] byte2 = System.Text.ASCIIEncoding.Default.GetBytes(s);
// Byte[] to string
string str = System.Text.Encoding.UTF8.GetString(byte1);
よくわかりませんが、文字列はその情報をCharの配列として格納していると思います。これは、バイトでは非効率的です。具体的には、Charの定義は「Unicode文字を表す」です。
この例のサンプルを見てください:
String str = "asdf éß";
String str2 = "asdf gh";
EncodingInfo[] info = Encoding.GetEncodings();
foreach (EncodingInfo enc in info)
{
System.Console.WriteLine(enc.Name + " - "
+ enc.GetEncoding().GetByteCount(str)
+ enc.GetEncoding().GetByteCount(str2));
}
Unicodeの回答はどちらの場合も14バイトですが、UTF-8の回答は最初の場合は9バイト、2番目の場合は7バイトであることに注意してください。
したがって、文字列で使用されるバイトだけが必要な場合は、単にを使用しますEncoding.Unicode
が、ストレージスペースでは非効率になります。
重要な問題は、文字列内のグリフには 32 ビット (文字コードの場合は 16 ビット) が必要ですが、1 バイトには 8 ビットしかないことです。ASCII 文字のみを含む文字列に制限しない限り、1 対 1 のマッピングは存在しません。System.Text.Encoding には、文字列を byte[] にマップする方法がたくさんあります。情報の損失を回避し、クライアントが byte[] を文字列にマップし直す必要があるときに使いやすい方法を選択する必要があります。 .
Utf8 は一般的なエンコーディングで、コンパクトで損失がありません。
最速の方法
public static byte[] GetBytes(string text)
{
return System.Text.ASCIIEncoding.UTF8.GetBytes(text);
}
マコトサン がコメントしたように編集すると、これが最良の方法になりました。
Encoding.UTF8.GetBytes(text)
次のコードを使用して、.NET でastring
を aに変換できます。byte array
string s_unicode = "abcéabc";
byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(s_unicode);
文字列の基になるバイトのコピーが本当に必要な場合は、次のような関数を使用できます。ただし、その理由を知るために読み進めないでください。
[DllImport(
"msvcrt.dll",
EntryPoint = "memcpy",
CallingConvention = CallingConvention.Cdecl,
SetLastError = false)]
private static extern unsafe void* UnsafeMemoryCopy(
void* destination,
void* source,
uint count);
public static byte[] GetUnderlyingBytes(string source)
{
var length = source.Length * sizeof(char);
var result = new byte[length];
unsafe
{
fixed (char* firstSourceChar = source)
fixed (byte* firstDestination = result)
{
var firstSource = (byte*)firstSourceChar;
UnsafeMemoryCopy(
firstDestination,
firstSource,
(uint)length);
}
}
return result;
}
この関数は、文字列の基になるバイトのコピーを非常に迅速に取得します。これらのバイトは、システムでエンコードされている方法で取得されます。このエンコーディングはほぼ確実に UTF-16LE ですが、これは実装の詳細であり、気にする必要はありません。
ただ呼び出す方が安全で、簡単で、信頼性が高くなります。
System.Text.Encoding.Unicode.GetBytes()
ほとんどの場合、これにより同じ結果が得られ、入力が容易になり、バイトが往復し、Unicode でのバイト表現が次のように呼び出されます。
System.Text.Encoding.Unicode.GetString()
String
to Byte[]
conversionの私の安全でない実装は次のとおりです。
public static unsafe Byte[] GetBytes(String s)
{
Int32 length = s.Length * sizeof(Char);
Byte[] bytes = new Byte[length];
fixed (Char* pInput = s)
fixed (Byte* pBytes = bytes)
{
Byte* source = (Byte*)pInput;
Byte* destination = pBytes;
if (length >= 16)
{
do
{
*((Int64*)destination) = *((Int64*)source);
*((Int64*)(destination + 8)) = *((Int64*)(source + 8));
source += 16;
destination += 16;
}
while ((length -= 16) >= 16);
}
if (length > 0)
{
if ((length & 8) != 0)
{
*((Int64*)destination) = *((Int64*)source);
source += 8;
destination += 8;
}
if ((length & 4) != 0)
{
*((Int32*)destination) = *((Int32*)source);
source += 4;
destination += 4;
}
if ((length & 2) != 0)
{
*((Int16*)destination) = *((Int16*)source);
source += 2;
destination += 2;
}
if ((length & 1) != 0)
{
++source;
++destination;
destination[0] = source[0];
}
}
}
return bytes;
}
それほどエレガントではないにしても、受け入れられているアンサーのものよりもはるかに高速です。10000000回の反復を超える私のストップウォッチベンチマークは次のとおりです。
[Second String: Length 20]
Buffer.BlockCopy: 746ms
Unsafe: 557ms
[Second String: Length 50]
Buffer.BlockCopy: 861ms
Unsafe: 753ms
[Third String: Length 100]
Buffer.BlockCopy: 1250ms
Unsafe: 1063ms
これを使用するには、プロジェクトのビルド プロパティで [安全でないコードを許可する] にチェックを入れる必要があります。.NET Framework 3.5 に従って、このメソッドは String 拡張としても使用できます。
public static unsafe class StringExtensions
{
public static Byte[] ToByteArray(this String s)
{
// Method Code
}
}
次の事実により、文字列はいくつかの異なる方法でバイト配列に変換できます。.NET は Unicode をサポートし、Unicode は UTF と呼ばれるいくつかの異なるエンコーディングを標準化します。それらはバイト表現の長さが異なりますが、文字列がエンコードされると文字列にコード化できるという意味では同等ですが、文字列が1つのUTFでエンコードされ、別のUTFを想定してデコードされる場合、ねじ込むことができます上。
また、.NET は非 Unicode エンコーディングをサポートしていますが、一般的には有効ではありません (ASCII などの実際の文字列で Unicode コード ポイントの限定されたサブセットが使用されている場合にのみ有効です)。内部的には、.NET は UTF-16 をサポートしていますが、ストリーム表現には通常 UTF-8 が使用されます。また、インターネットの標準デファクトでもあります。
当然のことながら、文字列のバイト配列へのシリアル化と逆シリアルSystem.Text.Encoding
化は、抽象クラスである class によってサポートされています。その派生クラスは具体的なエンコーディングをサポートしています:ASCIIEncoding
および 4 つの UTF ( System.Text.UnicodeEncoding
UTF-16 をサポート)
このリンクを参照してください。
を使用したバイト配列へのシリアライズ用System.Text.Encoding.GetBytes
。逆演算には を使用しますSystem.Text.Encoding.GetChars
。この関数は文字の配列を返すため、文字列を取得するには、文字列コンストラクターを使用しますSystem.String(char[])
。
このページを参照してください。
例:
string myString = //... some string
System.Text.Encoding encoding = System.Text.Encoding.UTF8; //or some other, but prefer some UTF is Unicode is used
byte[] bytes = encoding.GetBytes(myString);
//next lines are written in response to a follow-up questions:
myString = new string(encoding.GetChars(bytes));
byte[] bytes = encoding.GetBytes(myString);
myString = new string(encoding.GetChars(bytes));
byte[] bytes = encoding.GetBytes(myString);
//how many times shall I repeat it to show there is a round-trip? :-)
これは、Tyler が適切に言ったように、「文字列は純粋なデータではありません。情報も持っているからです。」この場合、情報は、文字列が作成されたときに想定されたエンコーディングです。
これは、彼自身の質問に対するOPのコメントに基づいており、ユースケースでのOPのヒントを理解していれば正しい質問です。
バイナリ データを文字列に格納することは、上記のエンコーディングが想定されているため、おそらく間違ったアプローチです。そのバイナリデータをstring
(より適切な配列ではなく)に保存したプログラムまたはライブラリが何であれbyte[]
、それが始まる前にすでに戦いに負けています。REST 要求/応答または文字列を送信する必要があるものでバイトを送信している場合は、 Base64が適切なアプローチです。
他の誰もがこの間違った質問に間違って答えました。
文字列がそのままで良さそうな場合は、エンコーディング (できれば UTF で始まるもの) を選択し、対応するSystem.Text.Encoding.???.GetBytes()
関数を使用して、選択したエンコーディングにバイトを渡す人に伝えます。
bytes[] buffer = UnicodeEncoding.UTF8.GetBytes(string something); //for converting to UTF then get its bytes
bytes[] buffer = ASCIIEncoding.ASCII.GetBytes(string something); //for converting to ascii then get its bytes
これを使用するだけです:
byte[] myByte= System.Text.ASCIIEncoding.Default.GetBytes(myString);
ふたつのやり方:
public static byte[] StrToByteArray(this string s)
{
List<byte> value = new List<byte>();
foreach (char c in s.ToCharArray())
value.Add(c.ToByte());
return value.ToArray();
}
と、
public static byte[] StrToByteArray(this string s)
{
s = s.Replace(" ", string.Empty);
byte[] buffer = new byte[s.Length / 2];
for (int i = 0; i < s.Length; i += 2)
buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
return buffer;
}
私は一番上のものよりも一番下のものをより頻繁に使用する傾向がありますが、速度についてはベンチマークしていません。
LINQ を使用した単純なコード
string s = "abc"
byte[] b = s.Select(e => (byte)e).ToArray();
編集:以下にコメントされているように、それは良い方法ではありません。
ただし、より適切なコーディングを使用して LINQ を理解するために使用できます。
string s = "abc"
byte[] b = s.Cast<byte>().ToArray();
受け入れられた回答に似たVisual Basic拡張機能を作成しましたが、変換に.NETメモリとマーシャリングを直接使用し、UnicodeEncoding.UTF8.GetString
またはUnicodeEncoding.UTF32.GetString
またはなどの他の方法でサポートされていない文字範囲をサポートしています( & &MemoryStream and BinaryFormatter
などの無効な文字):ChrW(55906)
ChrW(55655)
<Extension> _
Public Function ToBytesMarshal(ByRef str As String) As Byte()
Dim gch As GCHandle = GCHandle.Alloc(str, GCHandleType.Pinned)
Dim handle As IntPtr = gch.AddrOfPinnedObject
ToBytesMarshal = New Byte(str.Length * 2 - 1) {}
Try
For i As Integer = 0 To ToBytesMarshal.Length - 1
ToBytesMarshal.SetValue(Marshal.ReadByte(IntPtr.Add(handle, i)), i)
Next
Finally
gch.Free()
End Try
End Function
<Extension> _
Public Function ToStringMarshal(ByRef arr As Byte()) As String
Dim gch As GCHandle = GCHandle.Alloc(arr, GCHandleType.Pinned)
Try
ToStringMarshal = Marshal.PtrToStringAuto(gch.AddrOfPinnedObject)
Finally
gch.Free()
End Try
End Function
文字は、フォント テーブルへのルックアップ キーであると同時に、順序、大文字と小文字のバージョンなどの語彙の伝統でもあります。
したがって、文字はバイト (8 ビット) ではなく、バイトは文字ではありません。特に、1 バイトの 256 の順列は、すべての言語はおろか、一部の文字言語では数千の記号に対応できません。そのため、文字をエンコードするさまざまな方法が考案されています。特定のクラスの言語をエンコードするものもあります (ASCII エンコード)。コード ページ (拡張 ASCII) を使用した複数の言語。または、野心的に、必要に応じて追加のバイトを選択的に含めることにより、すべての言語、Unicode.
.NET フレームワークなどのシステム内では、String は特定の文字エンコーディングを意味します。.NET では、このエンコーディングは Unicode です。フレームワークはデフォルトで Unicode を読み書きするため、通常、.NET では文字エンコーディングを扱う必要はありません。
ただし、一般に、文字列をバイト ストリームからシステムにロードするには、ソース エンコーディングを知っている必要があります。したがって、それを正しく解釈し、その後正しく変換します (そうしないと、コードは既にシステムのデフォルト エンコーディングにあると見なされてレンダリングされます)。ちんぷんかんぷん)。同様に、文字列が外部ソースに書き込まれる場合、特定のエンコーディングで書き込まれます。
// C# to convert a string to a byte array.
public static byte[] StrToByteArray(string str)
{
System.Text.ASCIIEncoding encoding=new System.Text.ASCIIEncoding();
return encoding.GetBytes(str);
}
// C# to convert a byte array to a string.
byte [] dBytes = ...
string str;
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
str = enc.GetString(dBytes);
コードは次のとおりです。
// Input string.
const string input = "Dot Net Perls";
// Invoke GetBytes method.
// ... You can store this array as a field!
byte[] array = Encoding.ASCII.GetBytes(input);
// Loop through contents of the array.
foreach (byte element in array)
{
Console.WriteLine("{0} = {1}", element, (char)element);
}