And Brain said,
엔디언(Endian) 행진곡. 2 - Rust로 다시 쓰여지다 본문
엔디언(Endian) 행진곡
0. 멀티바이트의 질서있는 행진
1. 빅이냐 리틀이냐 그것이 문제로다
2. Rust로 다시 쓰여지다
3. 제1장: Network
4. 제2장: FIle
5. 행진이 끝나고
예제 코드
이제 Rust를 이용해 실제로 엔디언 변환을 해보도록 합시다.
Rust에서는 'byteorder' 라는 crate를 이용해 간편하게 엔디언 변환을 할 수 있습니다. 이 crate를 사용하여, 쉽게 데이터 바이트의 순서를 변경해보도록 합시다.
먼저, Cargo.toml 파일에 라이브러리를 추가해줍시다.
[dependencies]
byteorder = "1.4.3"
자, 이제 간단한 엔디언 변환 예제를 작성해봅시다.
use byteorder::{BigEndian, ByteOrder, LittleEndian};
fn main() {
let mut buf = [0; 4];
BigEndian::write_u32(&mut buf, 12345);
let n = BigEndian::read_u32(&buf);
buf.reverse(); // 바이트 배열 반전
let m = LittleEndian::read_u32(&buf);
assert_eq!(n, m); // 두 방식으로 읽은 값이 같음
}
n과 m은 각각 빅 엔디언과 리틀 엔디언 방식으로 바이트 배열을 읽은 변수입니다. 간단히 바이트 배열을 반전시키는 것만으로도 이 둘은 같아집니다.
이번엔 좀 더 복잡한 데이터 구조에서 엔디언 변환을 해봅시다. 구조체의 각 필드에 대한 엔디언 변환이 필요한 경우에는 'byteorde' crate의 'ReadBytesExt'와 'WriteBytesExt' 트레이트를 사용하면 편리합니다.
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
use std::io::Cursor;
#[derive(Debug)]
struct SimpleStruct {
field1: u32,
field2: u16,
field3: u8
}
fn main() {
let mut data = vec![];
let simple_struct = SimpleStruct {
field1: 12345,
field2: 6789,
field3: 101,
};
data.write_u32::<LittleEndian>(simple_struct.field1).unwrap();
data.write_u16::<LittleEndian>(simple_struct.field2).unwrap();
data.write_u8(simple_struct.field3).unwrap();
let mut cursor = Cursor::new(data);
let mut data_be = vec![];
let field1_le = cursor.read_u32::<LittleEndian>().unwrap();
let field2_le = cursor.read_u16::<LittleEndian>().unwrap();
let field3_le = cursor.read_u8().unwrap();
data_be.write_u32::<BigEndian>(field1_le).unwrap();
data_be.write_u16::<BigEndian>(field2_le).unwrap();
data_be.write_u8(field3_le).unwrap();
let mut cursor = Cursor::new(&data_be);
let simple_struct_be = SimpleStruct {
field1: cursor.read_u32::<BigEndian>().unwrap(),
field2: cursor.read_u16::<BigEndian>().unwrap(),
field3: cursor.read_u8().unwrap(),
};
println!("리틀 엔디언 {:?}", simple_struct);
println!("빅 엔디언 {:?}", simple_struct_be);
}
이렇게 구조체의 각 필드를 한 엔디언에서 다른 엔디언으로 변환할 수 있습니다.
이번엔 더 복잡한 구조체를 정의하고, 이를 빅 엔디언 형식의 바이트 배열로 변환한 후 다시 구조체로 변환해보도록 하겠습니다.
use byteorder::{BigEndian, LittleEndian, ReadBytesExt, WriteBytesExt};
use std::io::Cursor;
#[derive(Debug)]
struct ComplexStruct {
field1: u32,
field2: u16,
field3: u8,
field4: Vec<u32>,
}
impl ComplexStruct {
fn new() -> Self {
ComplexStruct {
field1: 12345,
field2: 6789,
field3: 101,
field4: vec![1, 2, 3, 4, 5],
}
}
fn to_big_endian(&self) -> Vec<u8> {
let mut data_be = vec![];
data_be.write_u32::<BigEndian>(self.field1).unwrap();
data_be.write_u16::<BigEndian>(self.field2).unwrap();
data_be.write_u8(self.field3).unwrap();
for &item in &self.field4 {
data_be.write_u32::<BigEndian>(item).unwrap();
}
data_be
}
fn from_big_endian(data: &[u8]) -> Self {
let mut cursor = Cursor::new(data);
let field1_be = cursor.read_u32::<BigEndian>().unwrap();
let field2_be = cursor.read_u16::<BigEndian>().unwrap();
let field3_be = cursor.read_u8().unwrap();
let mut field4_be = vec![];
while cursor.position() < data.len() as u64 {
field4_be.push(cursor.read_u32::<BigEndian>().unwrap());
}
ComplexStruct {
field1: field1_be,
field2: field2_be,
field3: field3_be,
field4: field4_be,
}
}
}
fn main() {
let complex_struct = ComplexStruct::new();
let data_be = complex_struct.to_big_endian();
println!("Original data: {:?}", complex_struct);
println!("BigEndian data: {:?}", data_be);
let complex_struct_be = ComplexStruct::from_big_endian(&data_be);
println!("Data from BigEndian: {:?}", complex_struct_be)
}
위 예제는 ComplexStruct라는 복잡한 구조체를 정의하고, 필드의 초기값과 직렬화/역직렬화 메서드를 제공합니다. to_big_endian() 메서드를 사용하여 ComplexStruct 인스턴스의 데이터를 빅 엔디언으로 직렬화하고, from_big_endian() 함수를 사용하여 빅 엔디언 데이터를 역직렬화하는 방법을 보여줍니다. main() 함수에서는 원본 데이터와 빅 엔디언 데이터를 출력하고, 역직렬화된 데이터를 다시 얻어 출력하여 작동을 확인합니다.
이와 같은 방식으로 더 복잡한 데이터 구조의 엔디언 변환도 처리할 수 있습니다.
<- 이전으로
다음으로 ->
Thanks for watching, Have a nice day.
'IT > 엔디언 행진곡' 카테고리의 다른 글
엔디언(Endian) 행진곡. 4 - 제2장: File (0) | 2023.07.13 |
---|---|
엔디언(Endian) 행진곡. 3 - 제1장: Network (0) | 2023.07.05 |
엔디언(Endian) 행진곡. 1 - 빅이냐 리틀이냐 그것이 문제로다 (0) | 2023.06.18 |
엔디언(Endian) 행진곡. 0 - 멀티바이트의 질서있는 행진 (0) | 2023.06.18 |