# Reverse byte order

This is a real world use case of how to reverse byte order.

It’s used in the code for Bitcoin.

According to the book “Mastering Bitcoin” this may have been an “unintentional consequence of a design decision in early Bitcoin software”

If you want to try this in a bash shell :

``````\$ echo eb3ae38f27191aa5f3850dc9cad00492b88b72404f9da135698679268041c54a \
| fold -w2 | tac | tr -d "\n"
4ac541802679866935a19d4f40728bb89204d0cac90d85f3a51a19278fe33aeb``````

Ok, so we know the problem, next, make a brew and then we’ll write some code:

## Code

Here is the code to reverse the byte order, let’s analyse it

``````fn main() {
let input = "eb3ae38f27191aa5f3850dc9cad00492b88b72404f9da135698679268041c54a";

// Reverse the order of each byte
let reversed = input
.as_bytes()
.chunks(2)
.rev()
.flat_map(|chunk| chunk.iter())
.map(|&byte| byte as char)
.collect::<String>();

// Remove newline characters
let result = reversed.replace("\n", "");

println!("{}", result);
}
``````

Let’s break down each part of the code:

• `as_bytes()`
• `as_bytes()` is a method available for strings in Rust that converts a string into a sequence of bytes. Each character in the string is represented by one or more bytes.
• `.chunks(2)`
• `chunks(2)` is a method provided by the `Iterator` trait in Rust. It transforms the sequence of bytes into an iterator of chunks, where each chunk contains 2 elements. In this case, it groups the bytes into pairs.
• `.rev()`
• `rev()` is another method from the `Iterator` trait. It reverses the order of elements in the iterator. So, after calling `.rev()`, the order of the pairs is reversed.
• `.flat_map(|chunk| chunk.iter())`
• `flat_map` is a method that both flattens and maps. In this context, it is used to flatten the iterator of pairs into a single iterator of bytes. The closure `(|chunk| chunk.iter())` is applied to each pair, and `iter()` is used to iterate over the bytes within the pair.
• `.map(|&byte| byte as char)`
• `map` is another method from the `Iterator` trait. It transforms each element in the iterator. Here, it is used to convert each byte into a character. The `|&byte|` syntax is a closure that takes a reference to each byte and converts it to a `char`.

In summary, this chain of methods takes a hexadecimal string, converts it to a sequence of bytes, groups the bytes into pairs, reverses the order of the pairs, flattens them into a single sequence of bytes, and finally, converts each byte to a character. This process effectively reverses the order of each byte in the original string.

## Step by Step

as_bytes()

chunks()

rev()

Note: We only saw the actual effect of as_bytes, chunks, and rev once we had used collect() at the end. (line 11)

## So how does flat_map work?

``````fn main() {
// Define a vector of vectors of integers
let numbers = vec![vec![1, 2, 3], vec![4, 5, 6], vec![7, 8, 9]];

// Use flat_map to flatten the vector of vectors into integers
let flattened_numbers: Vec<i32> = numbers
.iter()
.flat_map(|vec| vec.iter().cloned())
.collect();

// Print the original vector of vectors and the flattened vector of integers
println!("Original numbers: {:?}", numbers);
println!("Flattened integers: {:?}", flattened_numbers);
}``````
``````Original numbers: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Flattened integers: [1, 2, 3, 4, 5, 6, 7, 8, 9]

[Process exited 0]``````

Note the use of cloned() in our code?

The use of `cloned()` is often associated with `flat_map` when you want to work with owned values rather than references.

The `flat_map` method expects the closure passed to it to return an iterator, and it flattens the resulting iterators into a single iterator. If the original iterator yields references to values, using `cloned()` is a way to create a new iterator where each element is cloned, turning references into owned values. This is necessary because the resulting iterator from `flat_map` will combine elements from multiple iterators, and each element needs to have ownership.

In Rust, when you have a collection of references (`&T`), and you want to transform them into owned values (`T`), you often use the `cloned()` method on the iterator. This ensures that you get a new iterator containing owned copies of the original values.