I want to convert from int to hex in Golang.
In strconv, there is a method that converts strings to hex. Is there a similar method to get a hex string from an int?
Since hex is a Integer literal, you can ask the fmt package for a string representation of that integer, using fmt.Sprintf(), and the %x or %X format.
See playground
i := 255
h := fmt.Sprintf("%x", i)
fmt.Printf("Hex conv of '%d' is '%s'\n", i, h)
h = fmt.Sprintf("%X", i)
fmt.Printf("HEX conv of '%d' is '%s'\n", i, h)
Output:
Hex conv of '255' is 'ff'
HEX conv of '255' is 'FF'
"Hex" isn't a real thing. You can use a hexadecimal representation of a number, but there's no difference between 0xFF and 255. More info on that can be found in the docs which point out you can use 0xff to define an integer constant 255! As you mention, if you're trying to find the hexadecimal representation of an integer you could use strconv
package main
import (
"fmt"
"strconv"
)
func main() {
fmt.Println(strconv.FormatInt(255, 16))
// gives "ff"
}
Try it in the playground
If formatting some bytes, hex needs a 2 digits representation, with leading 0.
For exemple: 1 => '01', 15 => '0f', etc.
It is possible to force Sprintf to respect this :
h:= fmt.Sprintf("%02x", 14)
fmt.Println(h) // 0e
h2:= fmt.Sprintf("%02x", 231)
fmt.Println(h2) // e7
The pattern "%02x" means:
'0' force using zeros
'2' set the output size as two charactes
'x' to convert in hexadecimal
i := 4357640193405743614
h := fmt.Sprintf("%016x",i)
fmt.Printf("Decimal: %d,\nHexa: %s", i, h)
# Result
Decimal..: 4357640193405743614,
Hexa.....: 3c7972ab0ae9f1fe
Playground: https://play.golang.org/p/ndlMyBdQjmT
Sprintf is more versatile but FormatInt is faster. Choose what is better for you
func Benchmark_sprintf(b *testing.B) { // 83.8 ns/op
for n := 0; n < b.N; n++ {
_ = fmt.Sprintf("%x", n)
}
}
func Benchmark_formatint(b *testing.B) { // 28.5 ns/op
bn := int64(b.N)
for n := int64(0); n < bn; n++ {
_ = strconv.FormatInt(n, 16)
}
}
E.g. if its uint32, you can convert it to HEX as seen below =>
var p uint32
p = 4278190335
r := p >> 24 & 0xFF
g := p >> 16 & 0xFF
b := p >> 8 & 0xFF
fmt.Println(r, g, b)//255 0 0
DEMO
you can also check this online tool for ref. https://cryptii.com/pipes/integer-encoder
Related
I have to do a cryptography project for my school and I choose Go for this project !
I read the doc but I only C, so it's kinda hard for me right now.
First , I needed to collect the program arguments, I did it. I stockd all arguments in a string variable like :
var text, base string = os.Args[1], os. Args[6]
Now , i need to store the ASCII number in a array of int , for exemple , in C I would done something like that :
int arr[18];
char str[18] = "Hi Stack OverFlow";
arr[i] = str[i] - 96;
So how could I do that in Go?
Thanks !
Here's an example that is similar to the other answer but avoids importing additional packages.
Create a slice of int with the length equal to the string's length. Then iterate over the string to extract each character as int and assign it to the corresponding index in the int slice. Here's code (also on the Go Playground):
package main
import "fmt"
func main() {
s := "Hi Stack OverFlow"
fmt.Println(StringToInts(s))
}
// makes a slice of int and stores each char from string
// as int in the slice
func StringToInts(s string) (intSlice []int) {
intSlice = make([]int, len(s))
for i, _ := range s {
intSlice[i] = int(s[i])
}
return
}
Output of the above program is:
[72 105 32 83 116 97 99 107 32 79 118 101 114 70 108 111 119]
The StringToInts function in the above should do what you want. Though it returns a slice (not an array) of int, it should satisfy your usecase.
My guess is that you want something like this:
package main
import (
"fmt"
"strings"
)
// transform transforms ASCII letters to numbers.
// Letters in the English (basic Latin) alphabet, both upper and lower case,
// are represented by a number between one and twenty-six. All other characters,
// including space, are represented by the number zero.
func transform(s string) []int {
n := make([]int, 0, len(s))
other := 'a' - 1
for _, r := range strings.ToLower(s) {
if 'a' > r || r > 'z' {
r = other
}
n = append(n, int(r-other))
}
return n
}
func main() {
s := "Hi Stack OverFlow"
fmt.Println(s)
n := transform(s)
fmt.Println(n)
}
Output:
Hi Stack OverFlow
[8 9 0 19 20 1 3 11 0 15 22 5 18 6 12 15 23]
Take A Tour of Go and see if you can understand what the program does.
I am new to go lang and I want to print the individual byte of array of string
as in below code I want to print the values 'h','e','l','l','o' once at a time but I am not able to do the same.
func main() {
strslice := make([]string, 4, 5)
strslice[0] = "hello"
strslice[1] = "go"
strslice[2] = "lang"
strslice[3] = "whatsup"
for i := 0; i < len(strslice[i]); i++ {
fmt.Printf("slice is %c \n", strslice[i])
}
}
In Go, character literals are stored in a string as a variable-width sequence of UTF-8 encoded bytes. The ASCII code points (0x00..0x7F) occupy one byte. Other code points occupy two to four bytes. To print code points (characters) separately,
package main
import "fmt"
func main() {
strslice := make([]string, 5, 5)
strslice[0] = "hello"
strslice[1] = "go"
strslice[2] = "lang"
strslice[3] = "whatsup"
strslice[4] = "Hello, 世界"
for _, s := range strslice {
for _, c := range s {
fmt.Printf("%c ", c)
}
fmt.Printf("\n")
}
}
Output:
h e l l o
g o
l a n g
w h a t s u p
H e l l o , 世 界
Here's an illustration of the difference between UTF-8 encoded bytes and characters,
package main
import "fmt"
func main() {
str := "Hello, 世界"
fmt.Println("Bytes:")
for i := 0; i < len(str); i++ {
fmt.Printf("'%c' ", str[i])
}
fmt.Printf("\n")
fmt.Println("Characters:")
for _, c := range str {
fmt.Printf("'%c' ", c)
}
fmt.Printf("\n")
}
Output:
Bytes:
'H' 'e' 'l' 'l' 'o' ',' ' ' 'ä' '¸' '' 'ç' '' ''
Characters:
'H' 'e' 'l' 'l' 'o' ',' ' ' '世' '界'
References:
Unicode UTF-8 FAQ
For statements, The Go Programming Language Specification
One possible approach:
func main() {
strslice := make([]string, 4, 5)
strslice[0] = "hello"
strslice[1] = "go"
strslice[2] = "lang"
strslice[3] = "whatsup"
for i := 0; i < len(strslice); i++ {
for j := 0; j < len(strslice[i]); j++ {
fmt.Printf("slice[%d] is %c \n", i, strslice[i][j])
}
}
}
Demo. As you see, each strslice element is iterated in a nested for loop, using its own loop variable (j).
In strslice[i][j], i is used to access an element of slice (a string), and j is used to access a specific byte of this string.
Note that it's byte, not character - because that's exactly what has been asked. But check wonderful #peterSO's answer if you actually want to print out each character of the string - as there's a big chance you do. )
In the following code, I iterate over a string rune by rune, but I'll actually need an int to perform some checksum calculation. Do I really need to encode the rune into a []byte, then convert it to a string and then use Atoi to get an int out of the rune? Is this the idiomatic way to do it?
// The string `s` only contains digits.
var factor int
for i, c := range s[:12] {
if i % 2 == 0 {
factor = 1
} else {
factor = 3
}
buf := make([]byte, 1)
_ = utf8.EncodeRune(buf, c)
value, _ := strconv.Atoi(string(buf))
sum += value * factor
}
On the playground: http://play.golang.org/p/noWDYjn5rJ
The problem is simpler than it looks. You convert a rune value to an int value with int(r). But your code implies you want the integer value out of the ASCII (or UTF-8) representation of the digit, which you can trivially get with r - '0' as a rune, or int(r - '0') as an int. Be aware that out-of-range runes will corrupt that logic.
For example, sum += (int(c) - '0') * factor,
package main
import (
"fmt"
"strconv"
"unicode/utf8"
)
func main() {
s := "9780486653556"
var factor, sum1, sum2 int
for i, c := range s[:12] {
if i%2 == 0 {
factor = 1
} else {
factor = 3
}
buf := make([]byte, 1)
_ = utf8.EncodeRune(buf, c)
value, _ := strconv.Atoi(string(buf))
sum1 += value * factor
sum2 += (int(c) - '0') * factor
}
fmt.Println(sum1, sum2)
}
Output:
124 124
why don't you do only "string(rune)".
s:="12345678910"
var factor,sum int
for i,x:=range s{
if i%2==0{
factor=1
}else{
factor=3
}
xstr:=string(x) //x is rune converted to string
xint,_:=strconv.Atoi(xstr)
sum+=xint*factor
}
fmt.Println(sum)
val, _ := strconv.Atoi(string(v))
Where v is a rune
More concise but same idea as above
Is there a built-in function to convert a uint to a slice of binary integers {0,1} ?
>> convert_to_binary(2)
[1, 0]
I am not aware of such a function, however you can use strconv.FormatUint for that purpose.
Example (on play):
func Bits(i uint64) []byte {
bits := []byte{}
for _, b := range strconv.FormatUint(i, 2) {
bits = append(bits, byte(b - rune('0')))
}
return bits
}
FormatUint will return the string representation of the given uint to a base, in this case 2, so we're encoding it in binary. So the returned string for i=2 looks like this: "10". In bytes this is [49 48] as 1 is 49 and 0 is 48 in ASCII and Unicode. So we just need to iterate over the string, subtracting 48 from each rune (unicode character) and converting it to a byte.
Here is another method:
package main
import (
"bytes"
"fmt"
"math/bits"
)
func unsigned(x uint) []byte {
b := make([]byte, bits.UintSize)
for i := range b {
if bits.LeadingZeros(x) == 0 {
b[i] = 1
}
x = bits.RotateLeft(x, 1)
}
return b
}
func trimUnsigned(x uint) []byte {
return bytes.TrimLeft(unsigned(x), string(0))
}
func main() {
b := trimUnsigned(2)
fmt.Println(b) // [1 0]
}
https://golang.org/pkg/math/bits#LeadingZeros
http://play.golang.org/p/ZsALO8oF3W
I want to traverse a string and return the character values. How do I, not return the numeric values per each letter, and return the actual characters?
Now I am getting this
0 72 72
1 101 101
2 108 108
3 108 108
4 111 111
My desired output would be
0 h h
1 e e
2 l l
3 l l
4 o o
package main
import "fmt"
func main() {
str := "Hello"
for i, elem := range str {
fmt.Println(i, str[i], elem)
}
for elem := range str {
fmt.Println(elem)
}
}
Thanks,
For statements
For a string value, the "range" clause iterates over the Unicode code
points in the string starting at byte index 0. On successive
iterations, the index value will be the index of the first byte of
successive UTF-8-encoded code points in the string, and the second
value, of type rune, will be the value of the corresponding code
point. If the iteration encounters an invalid UTF-8 sequence, the
second value will be 0xFFFD, the Unicode replacement character, and
the next iteration will advance a single byte in the string.
For example,
package main
import "fmt"
func main() {
str := "Hello"
for _, r := range str {
c := string(r)
fmt.Println(c)
}
fmt.Println()
for i, r := range str {
fmt.Println(i, r, string(r))
}
}
Output:
H
e
l
l
o
0 72 H
1 101 e
2 108 l
3 108 l
4 111 o
package main
Use Printf to indicate you want to print characters.
import "fmt"
func main() {
str := "Hello"
for i, elem := range str {
fmt.Printf("%d %c %c\n", i, str[i], elem)
}
}
The way you are iterating over the characters in the string is workable (although str[i] and elem are the duplicative of each other). You have the right data.
In order to get it to display correctly, you just need to output with the right formatting (i.e. interpreted as a unicode character rather than an int).
Change:
fmt.Println(i, str[i], elem)
to:
fmt.Printf("%d %c %c\n", i, str[i], elem)
%c is the character represented by the corresponding Unicode code point per the Printf doc: http://golang.org/pkg/fmt/