Bagaimana cara mengonversikan string
ke byte[]
dalam .NET (C #) tanpa secara manual menentukan pengkodean tertentu?
Saya akan mengenkripsi string. Saya dapat mengenkripsi tanpa mengubah, tetapi saya masih ingin tahu mengapa encoding datang untuk bermain di sini.
Juga, mengapa pengkodean harus dipertimbangkan? Tidak bisakah saya mendapatkan byte apa yang telah disimpan oleh string? Mengapa ada ketergantungan pada pengkodean karakter?
c#
.net
string
character-encoding
Agnel Kurian
sumber
sumber
Jawaban:
Bertentangan dengan jawaban di sini, Anda TIDAK perlu khawatir tentang penyandian jika byte tidak perlu ditafsirkan!
Seperti yang Anda sebutkan, tujuan Anda adalah, sederhana, untuk "mendapatkan byte apa yang disimpan oleh string" .
(Dan, tentu saja, untuk dapat membangun kembali string dari byte.)
Untuk tujuan-tujuan itu, sejujurnya saya tidak mengerti mengapa orang-orang terus mengatakan kepada Anda bahwa Anda perlu pengkodean. Anda tentu TIDAK perlu khawatir tentang pengkodean untuk ini.
Lakukan saja ini sebagai gantinya:
Selama program Anda (atau program lain) tidak mencoba menafsirkan byte entah bagaimana, yang Anda jelas tidak menyebutkan Anda ingin lakukan, maka tidak ada yang salah dengan pendekatan ini! Khawatir tentang penyandian hanya membuat hidup Anda lebih rumit tanpa alasan yang nyata.
Manfaat tambahan untuk pendekatan ini:
Tidak masalah jika string berisi karakter yang tidak valid, karena Anda tetap bisa mendapatkan data dan merekonstruksi string asli!
Ini akan dikodekan dan didekodekan sama saja, karena Anda hanya melihat byte .
Jika Anda menggunakan pengodean tertentu, itu akan memberi Anda masalah dengan pengodean / decoding karakter yang tidak valid.
sumber
GetString
danGetBytes
perlu dieksekusi pada sistem dengan endianness yang sama untuk bekerja. Jadi Anda tidak dapat menggunakan ini untuk mendapatkan byte yang ingin Anda ubah menjadi string di tempat lain. Jadi saya memiliki waktu yang sulit untuk menemukan situasi di mana saya ingin menggunakan ini.Itu tergantung pada pengkodean string Anda ( ASCII , UTF-8 , ...).
Sebagai contoh:
Contoh kecil mengapa penyandian penting:
ASCII sama sekali tidak dilengkapi untuk berurusan dengan karakter khusus.
Secara internal, .NET framework menggunakan UTF-16 untuk mewakili string, jadi jika Anda hanya ingin mendapatkan byte yang tepat yang digunakan .NET, gunakan
System.Text.Encoding.Unicode.GetBytes (...)
.Lihat Pengodean Karakter di .NET Framework (MSDN) untuk informasi lebih lanjut.
sumber
Jawaban yang diterima sangat, sangat rumit. Gunakan kelas .NET yang disertakan untuk ini:
Jangan menemukan kembali roda jika Anda tidak perlu ...
sumber
System.Text.Encoding.Unicode
setara dengan jawaban Mehrdad.System.Text.Encoding.Unicode.GetBytes
mungkin akan lebih tepat.sumber
Anda perlu mempertimbangkan penyandian, karena 1 karakter dapat diwakili oleh 1 atau lebih byte (hingga sekitar 6), dan penyandian yang berbeda akan memperlakukan byte ini secara berbeda.
Joel memiliki posting tentang ini:
sumber
Ini pertanyaan populer. Penting untuk memahami apa yang ditanyakan oleh penulis pertanyaan, dan berbeda dari apa yang mungkin merupakan kebutuhan paling umum. Untuk mencegah penyalahgunaan kode yang tidak diperlukan, saya sudah jawab yang pertama.
Kebutuhan Umum
Setiap string memiliki rangkaian karakter dan pengodean. Saat Anda mengonversi
System.String
objek ke array,System.Byte
Anda masih memiliki kumpulan karakter dan pengodean. Untuk sebagian besar penggunaan, Anda akan tahu set karakter dan penyandian yang Anda butuhkan dan .NET membuatnya mudah untuk "menyalin dengan konversi." Pilih sajaEncoding
kelas yang sesuai .Konversi mungkin perlu menangani kasus di mana karakter target yang ditetapkan atau pengodean tidak mendukung karakter yang ada di sumber. Anda memiliki beberapa pilihan: pengecualian, penggantian atau lewati. Kebijakan default adalah mengganti '?'.
Jelas, konversi tidak harus rugi!
Catatan: Untuk
System.String
rangkaian karakter sumber adalah Unicode.Satu-satunya hal yang membingungkan adalah .NET menggunakan nama set karakter untuk nama satu pengkodean set karakter tertentu.
Encoding.Unicode
harus dipanggilEncoding.UTF16
.Itu saja untuk sebagian besar penggunaan. Jika itu yang Anda butuhkan, berhenti membaca di sini. Lihat artikel Joel Spolsky yang menyenangkan jika Anda tidak mengerti apa itu encoding.
Kebutuhan Khusus
Sekarang, penulis pertanyaan bertanya, "Setiap string disimpan sebagai array byte, kan? Mengapa saya tidak bisa hanya memiliki byte itu?"
Dia tidak menginginkan pertobatan.
Dari spesifikasi C # :
Jadi, kita tahu bahwa jika kita meminta konversi nol (yaitu, dari UTF-16 ke UTF-16), kita akan mendapatkan hasil yang diinginkan:
Tetapi untuk menghindari penyebutan encoding, kita harus melakukannya dengan cara lain. Jika tipe data antara dapat diterima, ada jalan pintas konseptual untuk ini:
Itu tidak memberikan kita tipe data yang diinginkan tetapi jawaban Mehrdad menunjukkan bagaimana mengubah array Char ini menjadi array Byte menggunakan BlockCopy . Namun, ini menyalin string dua kali! Dan, itu juga secara eksplisit menggunakan kode khusus pengkodean: tipe data
System.Char
.Satu-satunya cara untuk mendapatkan byte aktual dari String yang disimpan adalah dengan menggunakan pointer. The
fixed
pernyataan memungkinkan mengambil alamat nilai-nilai. Dari spesifikasi C #:Untuk melakukannya, kompiler menulis kode lompati bagian lain dari objek string
RuntimeHelpers.OffsetToStringData
. Jadi, untuk mendapatkan byte mentah, buat saja pointer ke string dan salin jumlah byte yang dibutuhkan.Seperti @CodesInChaos tunjukkan, hasilnya tergantung pada endianness dari mesin. Tetapi penulis pertanyaan tidak peduli dengan itu.
sumber
Length
PropertiString
mengembalikan jumlahChar
objek dalam contoh ini, bukan jumlah karakter Unicode." Karena itu kode contoh Anda sudah benar seperti yang tertulis.new String(new []{'\uD800', '\u0030'})
Globalization.SortKey
, mengekstraksiKeyData
, dan mengemas byte yang dihasilkan dari masing-masing ke dalamString
[dua byte per karakter, MSB pertama ], memanggilString.CompareOrdinal
string yang dihasilkan akan jauh lebih cepat daripada memanggilSortKey.Compare
instanceSortKey
, atau bahkan memanggilmemcmp
contoh-contoh itu. Mengingat itu, saya bertanya-tanya mengapaKeyData
mengembalikanByte[]
bukanString
?Bagian pertama dari pertanyaan Anda (cara mendapatkan byte) sudah dijawab oleh orang lain: lihat di
System.Text.Encoding
namespace.Saya akan menjawab pertanyaan tindak lanjut Anda: mengapa Anda perlu memilih penyandian? Mengapa Anda tidak bisa mendapatkannya dari kelas string itu sendiri?
Jawabannya ada dalam dua bagian.
Pertama-tama, byte yang digunakan secara internal oleh kelas string tidak penting , dan kapan pun Anda menganggapnya, Anda kemungkinan besar akan memperkenalkan bug.
Jika program Anda sepenuhnya dalam dunia. Net maka Anda tidak perlu khawatir tentang mendapatkan array byte untuk string sama sekali, bahkan jika Anda mengirim data melalui jaringan. Sebagai gantinya, gunakan .Net Serialisasi untuk khawatir tentang pengiriman data. Anda tidak perlu lagi khawatir tentang byte yang sebenarnya: formatter serialisasi melakukannya untuk Anda.
Di sisi lain, bagaimana jika Anda mengirim byte ini di suatu tempat yang Anda tidak dapat menjamin akan menarik data dari aliran serial .Net? Dalam hal ini Anda tentu perlu khawatir tentang pengkodean, karena jelas sistem eksternal ini peduli. Jadi sekali lagi, byte internal yang digunakan oleh string tidak masalah: Anda harus memilih pengkodean sehingga Anda dapat secara eksplisit tentang pengkodean ini pada sisi penerima, bahkan jika itu adalah pengkodean yang sama yang digunakan secara internal oleh .Net.
Saya mengerti bahwa dalam hal ini Anda mungkin lebih suka menggunakan byte aktual yang disimpan oleh variabel string dalam memori jika memungkinkan, dengan gagasan bahwa itu mungkin menghemat pekerjaan menciptakan aliran byte Anda. Namun, saya katakan kepada Anda itu tidak penting dibandingkan dengan memastikan bahwa output Anda dipahami di ujung yang lain, dan untuk menjamin bahwa Anda harus eksplisit dengan pengkodean Anda. Selain itu, jika Anda benar-benar ingin mencocokkan byte internal Anda, Anda sudah bisa memilih
Unicode
pengkodean, dan mendapatkan penghematan kinerja itu.Yang membawa saya ke bagian kedua ... memilih
Unicode
encoding adalah mengatakan Net menggunakan byte yang mendasari. Anda harus memilih penyandian ini, karena ketika beberapa Unicode-Plus yang baru dilipat keluar, runtime .Net harus bebas untuk menggunakan model penyandian yang lebih baru dan lebih baik ini tanpa merusak program Anda. Tapi, untuk saat ini (dan masa depan yang dapat dilihat), hanya memilih pengkodean Unicode memberi Anda apa yang Anda inginkan.Penting juga untuk memahami string Anda harus ditulis ulang untuk ditransfer, dan itu melibatkan setidaknya beberapa terjemahan dari pola-bit bahkan ketika Anda menggunakan pengkodean yang cocok . Komputer perlu memperhitungkan hal-hal seperti Big vs Little Endian, urutan byte jaringan, paketisasi, informasi sesi, dll.
sumber
Hanya untuk menunjukkan bahwa jawaban suara Mehrdrad berfungsi, pendekatannya bahkan dapat bertahan pada karakter pengganti yang tidak berpasangan (yang banyak diratakan oleh jawaban saya, tetapi semua orang sama-sama bersalah, misalnya
System.Text.Encoding.UTF8.GetBytes
,System.Text.Encoding.Unicode.GetBytes
metode pengkodean itu tidak dapat bertahan sebagai pengganti tinggi. karakterd800
misalnya, dan mereka hanya mengganti karakter pengganti tinggi dengan nilaifffd
):Keluaran:
Cobalah dengan System.Text.Encoding.UTF8.GetBytes atau System.Text.Encoding.Unicode.GetBytes , mereka hanya akan mengganti karakter pengganti yang tinggi dengan nilai fffd
Setiap kali ada gerakan dalam pertanyaan ini, saya masih memikirkan serializer (baik itu dari Microsoft atau dari komponen pihak ke-3) yang dapat bertahan string bahkan mengandung karakter pengganti yang tidak berpasangan; Saya google ini setiap sekarang dan kemudian: serialisasi karakter pengganti berpasangan .NET . Ini tidak membuat saya kehilangan tidur, tetapi agak menjengkelkan ketika kadang-kadang ada seseorang yang mengomentari jawaban saya bahwa itu salah, namun jawaban mereka sama-sama cacat ketika menyangkut karakter pengganti yang tidak berpasangan.
Sial, Microsoft seharusnya baru saja menggunakan
System.Buffer.BlockCopy
dalam nyaBinaryFormatter
ツ谢谢!
sumber
System.Buffer.BlockCopy
internal, semua argumen orang-orang pengkodean-advokasi akan diperdebatkanFFFD
pada karakter itu. Jika Anda ingin melakukan manipulasi string manual, gunakan char [] seperti yang disarankan.System.String
adalah urutan abadi dariChar
; .NET selalu mengizinkanString
objek dibuat dari apa punChar[]
dan mengekspor kontennya ke yangChar[]
berisi nilai yang sama, bahkan jika aslinyaChar[]
berisi pengganti yang tidak berpasangan.Coba ini, jauh lebih sedikit kode:
sumber
System.Text.Encoding.UTF8.GetBytes("Árvíztűrő tükörfúrógép);
, dan menangis! Ini akan berhasil, tetapiSystem.Text.Encoding.UTF8.GetBytes("Árvíztűrő tükörfúrógép").Length != System.Text.Encoding.UTF8.GetBytes("Arvizturo tukorfurogep").Length
sementara"Árvíztűrő tükörfúrógép".Length == "Arvizturo tukorfurogep".Length
Yah, saya sudah membaca semua jawaban dan mereka tentang menggunakan encoding atau satu tentang serialisasi yang menjatuhkan pengganti yang tidak berpasangan.
Ini buruk ketika string, misalnya, berasal dari SQL Server mana ia dibangun dari penyimpanan byte array, misalnya, hash kata sandi. Jika kita membuang sesuatu darinya, itu akan menyimpan hash yang tidak valid, dan jika kita ingin menyimpannya dalam XML, kita ingin membiarkannya tetap utuh (karena penulis XML menjatuhkan pengecualian pada pengganti yang tidak berpasangan yang ditemukannya).
Jadi saya menggunakan Base64 encoding array byte dalam kasus seperti itu, tapi hei, di Internet hanya ada satu solusi untuk ini di C #, dan ada bug di dalamnya dan hanya satu cara, jadi saya sudah memperbaiki bug dan menulis kembali prosedur. Inilah Anda, para googler masa depan:
sumber
Convert.ToBase64String(arr);
konversi base64byte[] (data) <-> string (serialized data to store in XML file)
. Tetapi untuk mendapatkan inisialbyte[] (data)
saya perlu melakukan sesuatu dengan data binerString
yang berisi (itu cara MSSQL mengembalikannya kepada saya). Jadi fungsi di atas adalah untuk .String (binary data) <-> byte[] (easy accessible binary data)
Karena tidak ada yang namanya "byte dari string".
String (atau lebih umum, teks) terdiri dari karakter: huruf, angka, dan simbol lainnya. Itu saja. Komputer, bagaimanapun, tidak tahu apa-apa tentang karakter; mereka hanya bisa menangani byte. Oleh karena itu, jika Anda ingin menyimpan atau mengirim teks dengan menggunakan komputer, Anda perlu mengubah karakter menjadi byte. Bagaimana kamu melakukannya? Di sinilah pengkodean datang ke tempat kejadian.
Pengkodean hanyalah konvensi untuk menerjemahkan karakter logis ke byte fisik. Pengkodean yang paling sederhana dan paling dikenal adalah ASCII, dan itu semua yang Anda butuhkan jika Anda menulis dalam bahasa Inggris. Untuk bahasa lain, Anda akan membutuhkan penyandian yang lebih lengkap, karena salah satu dari Unicode ini merupakan pilihan paling aman saat ini.
Jadi, singkatnya, mencoba "mendapatkan byte dari sebuah string tanpa menggunakan penyandian" adalah tidak mungkin seperti "menulis teks tanpa menggunakan bahasa apa pun".
Ngomong-ngomong, saya sangat menyarankan Anda (dan siapa pun, dalam hal ini) untuk membaca kebijaksanaan kecil ini: Minimum Mutlak Setiap Pengembang Perangkat Lunak Sepenuhnya, Sepenuhnya Harus Tahu Tentang Unicode dan Karakter Set (Tanpa Alasan!)
sumber
C # untuk mengonversi a
string
menjadibyte
array:sumber
sumber
Anda dapat menggunakan kode berikut untuk konversi antara array string dan byte.
sumber
Dengan munculnya
Span<T>
dirilis dengan C # 7.2, teknik kanonik untuk menangkap representasi memori yang mendasari string ke array byte yang dikelola adalah:Mengubahnya kembali harus menjadi non-starter karena itu berarti Anda sebenarnya menafsirkan data entah bagaimana, tetapi demi kelengkapan:
Nama-nama
NonPortableCast
danDangerousGetPinnableReference
harus melanjutkan argumen bahwa Anda mungkin tidak boleh melakukan ini.Perhatikan bahwa bekerja dengan
Span<T>
membutuhkan menginstal paket System.Memory NuGet .Apapun, pertanyaan asli aktual dan komentar tindak lanjut menyiratkan bahwa memori yang mendasari tidak sedang "ditafsirkan" (yang saya asumsikan berarti tidak dimodifikasi atau dibaca di luar kebutuhan untuk menulis apa adanya), menunjukkan bahwa beberapa implementasi
Stream
kelas harus digunakan sebagai ganti alasan tentang data sebagai string sama sekali.sumber
Saya tidak yakin, tapi saya pikir string menyimpan informasinya sebagai array Chars, yang tidak efisien dengan byte. Secara khusus, definisi Char adalah "Merupakan karakter Unicode".
ambil contoh contoh ini:
Perhatikan bahwa jawaban Unicode adalah 14 byte di kedua contoh, sedangkan jawaban UTF-8 hanya 9 byte untuk yang pertama, dan hanya 7 untuk yang kedua.
Jadi jika Anda hanya ingin byte yang digunakan oleh string, cukup gunakan
Encoding.Unicode
, tetapi akan tidak efisien dengan ruang penyimpanan.sumber
Masalah utama adalah bahwa mesin terbang dalam string membutuhkan 32 bit (16 bit untuk kode karakter) tetapi byte hanya memiliki 8 bit untuk cadangan. Pemetaan satu-ke-satu tidak ada kecuali Anda membatasi diri pada string yang hanya berisi karakter ASCII. System.Text.Encoding memiliki banyak cara untuk memetakan string ke byte [], Anda harus memilih satu yang menghindari hilangnya informasi dan yang mudah digunakan oleh klien Anda ketika dia perlu memetakan byte [] kembali ke string. .
Utf8 adalah pengkodean yang populer, ringkas dan tidak lossy.
sumber
Menggunakan:
Hasilnya adalah:
sumber
Jalan tercepat
EDIT sebagai Makotosan berkomentar ini sekarang adalah cara terbaik:
sumber
Sebuah String dalam. NET mewakili teks sebagai urutan unit kode UTF-16, sehingga byte sudah dikodekan dalam memori di UTF-16.
Jawaban Mehrdad
Kamu bisa menggunakan jawaban Mehrdad , tetapi sebenarnya menggunakan pengodean karena karakternya adalah UTF-16. Itu panggilan ToCharArray yang melihat sumbernya menciptakan
char[]
dan menyalin memori secara langsung. Kemudian menyalin data ke array byte yang juga dialokasikan. Jadi di bawah tenda itu menyalin byte yang mendasarinya dua kali dan mengalokasikan array char yang tidak digunakan setelah panggilan.Jawaban Tom Blodget
Jawaban Tom Blodget adalah 20-30% lebih cepat daripada Mehrdad karena melompati langkah menengah mengalokasikan array char dan menyalin byte ke dalamnya, tetapi mengharuskan Anda mengkompilasi dengan
/unsafe
opsi. Jika Anda benar-benar tidak ingin menggunakan pengodean, saya pikir ini adalah cara untuk pergi. Jika Anda memasukkan login enkripsi Anda di dalamfixed
blok, Anda bahkan tidak perlu mengalokasikan array byte terpisah dan menyalin byte ke dalamnya.Karena itulah cara yang tepat untuk melakukannya.
string
adalah abstraksi.Menggunakan penyandian dapat memberikan masalah jika Anda memiliki 'string' dengan karakter yang tidak valid, tetapi itu tidak boleh terjadi. Jika Anda memasukkan data ke string dengan karakter yang tidak valid, Anda salah melakukannya. Anda mungkin harus menggunakan array byte atau pengkodean Base64 untuk memulai.
Jika Anda menggunakan
System.Text.Encoding.Unicode
, kode Anda akan lebih tangguh. Anda tidak perlu khawatir tentang endianness sistem yang akan dijalankan oleh kode Anda. Anda tidak perlu khawatir jika versi CLR berikutnya akan menggunakan pengkodean karakter internal yang berbeda.Saya pikir pertanyaannya bukan mengapa Anda ingin khawatir tentang pengkodean, tetapi mengapa Anda ingin mengabaikannya dan menggunakan sesuatu yang lain. Pengkodean dimaksudkan untuk mewakili abstraksi string dalam urutan byte.
System.Text.Encoding.Unicode
akan memberikan Anda sedikit encoding urutan endian byte dan akan melakukan hal yang sama pada setiap sistem, sekarang dan di masa depan.sumber
Pendekatan terdekat dengan pertanyaan OP adalah Tom Blodget, yang sebenarnya masuk ke objek dan mengekstrak byte. Saya katakan paling dekat karena itu tergantung pada implementasi Object String.
Tentu, tetapi di situlah kesalahan mendasar dalam pertanyaan muncul. String adalah objek yang dapat memiliki struktur data yang menarik. Kita sudah tahu itu, karena memungkinkan pengganti yang tidak berpasangan untuk disimpan. Mungkin menyimpan panjangnya. Mungkin menyimpan pointer ke masing-masing pengganti 'berpasangan' memungkinkan penghitungan cepat. Dll Semua byte tambahan ini bukan bagian dari data karakter.
Yang Anda inginkan adalah byte setiap karakter dalam sebuah array. Dan di situlah 'encoding' masuk. Secara default Anda akan mendapatkan UTF-16LE. Jika Anda tidak peduli dengan byte itu sendiri kecuali untuk perjalanan pulang pergi maka Anda dapat memilih pengkodean apa pun termasuk 'default', dan mengubahnya kembali nanti (dengan asumsi parameter yang sama seperti apa pengkodean default, titik kode, perbaikan bug , hal-hal yang diperbolehkan seperti pengganti yang tidak berpasangan, dll.
Tapi mengapa membiarkan 'pengkodean' menjadi sihir? Mengapa tidak menentukan pengkodean sehingga Anda tahu byte apa yang akan Anda dapatkan?
Pengkodean (dalam konteks ini) berarti byte yang mewakili string Anda. Bukan byte dari objek string. Anda ingin byte yang disimpan oleh string - di sinilah pertanyaan itu ditanyakan secara naif. Anda menginginkan byte string dalam array yang berdekatan yang mewakili string, dan tidak semua data biner lain yang mungkin berisi objek string.
Yang berarti bagaimana string disimpan tidak relevan. Anda ingin string "Dikodekan" menjadi byte dalam array byte.
Saya suka jawaban Tom Bloget karena dia membawa Anda ke arah 'byte dari objek string'. Ini tergantung implementasi, dan karena dia mengintip internal mungkin sulit untuk menyusun kembali salinan string.
Tanggapan Mehrdad salah karena menyesatkan pada tingkat konseptual. Anda masih memiliki daftar byte, yang disandikan. Solusi khususnyanya memungkinkan pengganti yang tidak berpasangan untuk dilestarikan - ini tergantung pada implementasi. Solusi khususnya tidak akan menghasilkan byte string secara akurat jika
GetBytes
mengembalikan string dalam UTF-8 secara default.Saya berubah pikiran tentang ini (solusi Mehrdad) - ini tidak mendapatkan byte dari string; melainkan mendapatkan byte dari array karakter yang dibuat dari string. Terlepas dari pengodean, char datatype di c # adalah ukuran tetap. Ini memungkinkan array byte panjang yang konsisten untuk diproduksi, dan memungkinkan array karakter direproduksi berdasarkan ukuran array byte. Jadi jika pengkodeannya adalah UTF-8, tetapi masing-masing karakter berukuran 6 byte untuk mengakomodasi nilai utf8 terbesar, itu masih akan berfungsi. Jadi memang - pengkodean karakter tidak masalah.
Tetapi konversi digunakan - setiap karakter ditempatkan ke dalam kotak ukuran tetap (tipe karakter c #). Namun, apa representasi itu tidak penting, yang secara teknis merupakan jawaban OP. Jadi - jika Anda tetap ingin mengonversi ... Kenapa tidak 'menyandikan'?
sumber
&(Char) 55906
&(Char) 55655
. Jadi Anda mungkin salah dan jawaban Mehrdad adalah konversi yang aman tanpa mempertimbangkan jenis pengkodean apa yang digunakan.Anda dapat menggunakan kode berikut untuk mengonversi a
string
menjadibyte array
.NETsumber
Jika Anda benar-benar menginginkan salinan byte yang mendasari string, Anda dapat menggunakan fungsi seperti yang berikut. Namun, Anda sebaiknya tidak membaca terus untuk mengetahui alasannya.
Fungsi ini akan memberi Anda salinan byte yang mendasari string Anda, cukup cepat. Anda akan mendapatkan byte-byte itu dengan cara apa pun mereka meng-encode pada sistem Anda. Pengkodean ini hampir pasti UTF-16LE tetapi itu adalah detail implementasi yang tidak perlu Anda pedulikan.
Akan lebih aman, lebih sederhana dan lebih dapat diandalkan untuk hanya menelepon,
Kemungkinan ini akan memberikan hasil yang sama, lebih mudah untuk mengetik, dan byte akan selalu pulang pergi dengan panggilan ke
sumber
Berikut ini adalah implementasi tidak aman saya
String
untukByte[]
konversi:Ini jauh lebih cepat daripada yang diterima, bahkan jika tidak seanggun itu. Berikut adalah tolok ukur Stopwatch saya lebih dari 10.000000 iterasi:
Untuk menggunakannya, Anda harus mencentang "Izinkan Kode Tidak Aman" di properti build proyek Anda. Sesuai .NET Framework 3.5, metode ini juga dapat digunakan sebagai ekstensi String:
sumber
RuntimeHelpers.OffsetToStringData
kelipatan 8 pada versi Itanium dari .NET? Karena kalau tidak, ini akan gagal karena bacaan yang tidak selaras.memcpy
? stackoverflow.com/a/27124232/659190Cukup gunakan ini:
sumber
System.Text.ASCIIEncoding.Default.GetBytes("Árvíztűrő tükörfúrógép.").ToString();
akan mengembalikan"Árvizturo tukörfurogép."
informasi yang hilang yang tidak dapat diambil. (Dan saya belum menyebutkan bahasa asia di mana Anda akan kehilangan semua karakter.)String dapat dikonversi ke byte array dalam beberapa cara berbeda, karena fakta berikut: .NET mendukung Unicode, dan Unicode menstandarisasi beberapa pengkodean perbedaan yang disebut UTF. Mereka memiliki panjang representasi byte yang berbeda tetapi setara dalam arti bahwa ketika string dikodekan, dapat dikodekan kembali ke string, tetapi jika string dikodekan dengan satu UTF dan didekodekan dengan asumsi UTF berbeda jika dapat dikacaukan naik.
Juga, .NET mendukung pengkodean non-Unicode, tetapi mereka tidak berlaku dalam kasus umum (akan valid hanya jika sub-set terbatas titik kode Unicode digunakan dalam string aktual, seperti ASCII). Secara internal, .NET mendukung UTF-16, tetapi untuk representasi aliran, UTF-8 biasanya digunakan. Ini juga merupakan standar-de-facto untuk Internet.
Tidak mengherankan, serialisasi string ke dalam array byte dan deserialization didukung oleh kelas
System.Text.Encoding
, yang merupakan kelas abstrak; kelas turunannya mendukung pengkodean konkret:ASCIIEncoding
dan empat UTF (System.Text.UnicodeEncoding
mendukung UTF-16)Ref tautan ini.
Untuk serialisasi ke array byte yang menggunakan
System.Text.Encoding.GetBytes
. Untuk penggunaan operasi terbalikSystem.Text.Encoding.GetChars
. Fungsi ini mengembalikan array karakter, jadi untuk mendapatkan string, gunakan konstruktor stringSystem.String(char[])
.Ref halaman ini.
Contoh:
sumber
Tergantung pada apa yang Anda inginkan untuk byte
Hal ini karena, sebagai Tyler sehingga tepat mengatakan , "Strings tidak data yang murni. Mereka juga memiliki informasi ." Dalam hal ini, informasi adalah pengkodean yang diasumsikan ketika string dibuat.
Dengan asumsi bahwa Anda memiliki data biner (bukan teks) yang disimpan dalam sebuah string
Ini didasarkan dari komentar OP pada pertanyaannya sendiri, dan merupakan pertanyaan yang tepat jika saya memahami petunjuk OP pada use-case.
Menyimpan data biner dalam string mungkin merupakan pendekatan yang salah karena asumsi pengkodean yang disebutkan di atas! Program atau pustaka apa pun yang menyimpan data biner dalam
string
(alih-alihbyte[]
array yang lebih cocok) telah kalah dalam pertarungan sebelum dimulai. Jika mereka mengirim byte kepada Anda dalam permintaan / tanggapan REST atau apa pun yang harus mengirimkan string, Base64 akan menjadi pendekatan yang tepat.Jika Anda memiliki string teks dengan pengkodean yang tidak dikenal
Semua orang menjawab pertanyaan yang salah ini dengan tidak benar.
Jika string terlihat bagus apa adanya, pilih saja suatu pengkodean (lebih disukai yang dimulai dengan UTF), gunakan
System.Text.Encoding.???.GetBytes()
fungsi yang sesuai , dan beri tahu siapa pun yang Anda berikan byte pada pengodean yang Anda pilih.sumber
Setelah ditanya apa yang ingin Anda lakukan dengan byte, Anda merespons :
Terlepas dari apakah Anda bermaksud mengirim data terenkripsi ini melalui jaringan, memuatnya kembali ke memori nanti, atau mengukusnya ke proses lain, Anda jelas bermaksud mendekripsi data itu di beberapa titik. Dalam hal ini, jawabannya adalah Anda mendefinisikan protokol komunikasi. Protokol komunikasi tidak boleh didefinisikan dalam hal rincian implementasi bahasa pemrograman Anda dan runtime terkait. Ada beberapa alasan untuk ini:
Untuk berkomunikasi (baik dengan proses yang sama sekali berbeda atau dengan program yang sama di masa mendatang), Anda perlu mendefinisikan protokol Anda secara ketat untuk meminimalkan kesulitan bekerja dengannya atau secara tidak sengaja membuat bug. Bergantung pada representasi internal .NET bukanlah definisi yang ketat, jelas, atau bahkan dijamin konsisten. Pengkodean standar adalah definisi ketat yang tidak akan mengecewakan Anda di masa mendatang.
Dengan kata lain, Anda tidak dapat memenuhi persyaratan Anda untuk konsistensi tanpa menentukan pengkodean.
Anda tentu dapat memilih untuk menggunakan UTF-16 secara langsung jika Anda menemukan bahwa proses Anda berkinerja lebih baik sejak. NET menggunakannya secara internal atau karena alasan lain, tetapi Anda harus memilih pengkodean secara eksplisit dan melakukan konversi tersebut secara eksplisit dalam kode Anda daripada tergantung pada implementasi internal .NET.
Jadi pilih pengodean dan gunakan:
Seperti yang Anda lihat, sebenarnya juga lebih sedikit kode untuk hanya menggunakan objek enkode bawaan daripada menerapkan metode pembaca / penulis Anda sendiri.
sumber
Dua arah:
Dan,
Saya cenderung menggunakan bagian bawah lebih sering daripada bagian atas, belum membandingkan mereka untuk kecepatan.
sumber
sumber