Printmemory
What's Printmemory
Printmemory is a function that prints the hexadecimal representation of every values of a byte array.
Base 10 and Base 16
We already use a base in the everyday life which is the base 10. Base 10 means that we can have 10 different values before going to the next digit.
When we are at 9 and we had 1, then we go one digit to the left, which gives us 10.
It's the exact same thing with base 16, we have 16 different values and when we get to 16, our number is 10.
Here is what happend:
base 10:
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10
base 16:
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> a -> b -> c -> d -> e -> f -> 10
Conversion
In the main function:
printmemory([10]byte{'h', 'e', 'l', 'l', 'o', 16, 21, '*'})
First step
tabascii := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"a", "b", "c", "d", "e", "f"}
Second step
first := 0
second := 0
for i := 0; i < 10; i++ {
first = int(rune(arr[i]) / 16)
second = int(rune(arr[i]) % 16)
}
- The result of the division by 16.
- The rest of the division by 16.
For example the letter "h" is 104 on the ascii table.
We can divide it 6 times by 16 -> 16 x 6 = 96.
And the rest of this division is 8 -> 96 + 8 = 104.
We then have 6 and 8, because 104 in base 16 is 68. We just need to store it to be able to show it after.
Third step
tabascii := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"a", "b", "c", "d", "e", "f"}
finaltab := []string{}
first := 0
second := 0
for i := 0; i < 10; i++ {
first = int(rune(arr[i]) / 16)
second = int(rune(arr[i]) % 16)
finaltab = append(finaltab, tabascii[first]+tabascii[second])
}
We use the int as an index of the tabascii array for 2 reasons:
- First we have an int and it's easier to deal with string with z01.PrintRune. So that way we get the string value of our int without converting it
- If our int is above 9, which is supposed to happend since we're dealing with base 16. That way if we have 10 as an int, it will convert it to "a".
Here is what we get:
finaltab = []string{"68", "65", "6c", "6c", "6f", "10", "15", "2a", "00", "00"}
Fourth step
for i := 0; i < 10; i++ {
PrintStr(finaltab[i])
if i == 3 || i == 7 || i == 9 {
z01.PrintRune('\n')
} else {
z01.PrintRune(' ')
}
}
As asked we have 4 values per line, so when i is equal to 3, 7 or 9 we need to add a "\n", otherwise it's just a space.
Here is what we get:
68 65 6c 6c
6f 10 15 2a
00 00
Fifth step
for i := 0; i < len(arr); i++ {
if rune(arr[i]) >= 32 && rune(arr[i]) <= 127 {
z01.PrintRune(rune(arr[i]))
} else {
z01.PrintRune('.')
}
}
Printable characters on the ascii table are from 32 to 127.
Here is what we get:
hello..*..
Full code
package main
import "github.com/01-edu/z01"
func PrintStr(s string) {
for i := 0; i < len(s); i++ {
z01.PrintRune(rune(s[i]))
}
}
func printmemory(arr [10]byte) {
tabascii := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"a", "b", "c", "d", "e", "f"}
finaltab := []string{}
first := 0
second := 0
for i := 0; i < 10; i++ {
first = int(rune(arr[i]) / 16)
second = int(rune(arr[i]) % 16)
finaltab = append(finaltab, tabascii[first]+tabascii[second])
}
for i := 0; i < 10; i++ {
PrintStr(finaltab[i])
if i == 3 || i == 7 || i == 9 {
z01.PrintRune('\n')
} else {
z01.PrintRune(' ')
}
}
for i := 0; i < len(arr); i++ {
if rune(arr[i]) >= 32 && rune(arr[i]) <= 127 {
z01.PrintRune(rune(arr[i]))
} else {
z01.PrintRune('.')
}
}
}
68 65 6c 6c
6f 10 15 2a
00 00
hello..*..