Saya perlu mengonversi satu int
ke byte[]
satu cara melakukannya adalah dengan menggunakannya BitConverter.GetBytes()
. Tetapi saya tidak yakin apakah itu cocok dengan spesifikasi berikut:
Integer bertanda XDR adalah datum 32-bit yang mengkodekan integer dalam kisaran [-2147483648,2147483647]. Bilangan bulat diwakili dalam notasi komplemen dua. Bytes paling signifikan dan paling sedikit adalah 0 dan 3, masing-masing. Integer dinyatakan sebagai berikut:
Sumber: RFC1014 3.2
Bagaimana saya bisa melakukan transformasi int ke byte yang akan memenuhi spesifikasi di atas?
c#
.net
bit-manipulation
nfs
Peter
sumber
sumber
Jawaban:
RFC hanya mencoba untuk mengatakan bahwa integer yang ditandatangani adalah integer 4-byte normal dengan byte yang dipesan dengan cara big-endian.
Sekarang, Anda kemungkinan besar bekerja pada mesin little-endian dan
BitConverter.GetBytes()
akan memberi Anda yangbyte[]
terbalik. Jadi Anda bisa mencoba:Untuk kode yang paling portabel, Anda dapat melakukannya seperti ini:
sumber
byte[] result = intBytes;
? belumintBytes
array yang Anda inginkan?result
berlebihan dalam bagian kode ini. Namun, saya merasa bahwa lebih pedagogis untuk secara eksplisit menunjukkan kepada pembaca apa hasilnya daripada berasumsi bahwa mereka dapat mengetahui bahwa hasilnya terkandung dalam beberapa variabel bernamaintBytes
. Selain itu, melakukan penugasan itu murah karena tidak menyalin memori atau mengalokasikan memori baru, itu hanya menambah nama baru ke array yang sudah dialokasikan. Jadi mengapa tidak melakukannya?Berikut cara lain untuk melakukannya: seperti yang kita ketahui 1x byte = 8x bit dan juga, integer "biasa" (int32) berisi 32 bit (4 byte). Kita dapat menggunakan operator >> untuk menggeser bit ke kanan (>> operator tidak mengubah nilai.)
sumber
& 0xFF
bit tidak diperlukan.unchecked
blok. Saat ini hanya berfungsi jika pemeriksaan integer overflow dinonaktifkan di pengaturan kompiler.BitConverter.GetBytes(int)
hampir melakukan apa yang Anda inginkan, kecuali endianness salah.Anda dapat menggunakan metode IPAddress.HostToNetwork untuk menukar byte dalam nilai integer sebelum menggunakan
BitConverter.GetBytes
atau menggunakan kelas EndianBitConverter Jon Skeet . Kedua metode melakukan hal yang benar (tm) mengenai portabilitas.sumber
Ketika saya melihat deskripsi ini, saya punya perasaan, bahwa bilangan bulat xdr ini hanya bilangan bulat "standar" big-endian, tapi itu diungkapkan dengan cara yang paling dikaburkan. Notasi komplemen dua lebih dikenal sebagai U2, dan itulah yang kami gunakan pada prosesor saat ini. Urutan byte menunjukkan bahwa ini adalah notasi big-endian .
Jadi, menjawab pertanyaan Anda, Anda harus membalikkan elemen dalam array Anda (0 <--> 3, 1 <--> 2), karena elemen-elemen tersebut dikodekan dalam little-endian. Hanya untuk memastikan, Anda harus terlebih dahulu memeriksa
BitConverter.IsLittleEndian
untuk melihat pada mesin apa yang Anda jalankan.sumber
Mengapa semua kode ini ada dalam contoh di atas ...
Struct dengan tata letak eksplisit bertindak dua arah dan tidak memiliki hit kinerja.
Pembaruan: Karena ada pertanyaan tentang cara menangani endianness, saya menambahkan antarmuka yang menggambarkan cara abstrak itu. Struktural pelaksana lain dapat menangani kasus sebaliknya
sumber
Jika Anda ingin informasi yang lebih umum tentang berbagai metode untuk mewakili angka termasuk Two's Complement, lihat:
Representasi Dua Pelengkap dan Nomor yang Ditandatangani di Wikipedia
sumber
Cara lain adalah dengan menggunakan BinaryPrimitive seperti itu
byte[] intBytes = BitConverter.GetBytes(123); int actual = BinaryPrimitives.ReadInt32LittleEndian(intBytes);
sumber
sumber
sumber
Int16
.