How to convert int16 to hex-encoded string in Golang - go

I need to convert the data format of an int16 to a string representing its hexadecimal value.
I have tried some hex converters but they change the data instead of changing the formatting. I need it to be a string representation of its hexadecimal value.
data := (data from buffer)
fmt.Printf("BUFFER DATA : %X\n", data) // output print on screen D9DC (hex)
fmt.Println(("BUFFER DATA : ", string(data)) // output print on screen 55772 (dec)
fmt.Println(("BUFFER DATA : ", data) // output print on screen [?]
How can I convert the data format so it prints D9DC with fmt.Println?
Full code here https://play.golang.org/p/WVpMb9lh1Rx

Since fmt.Println doesn't accept format flags, it prints each variable depending on its type.
crc16.Checksum returns an int16, so fmt.Println will display the integer value of your hexadecimal string, which is 55772.
If you want fmt.Println to print D9DC instead of the integer value, you have multiple choices.
Convert your integer into a string that contains the hexadecimal value (which means if you change your integer, you will need to convert it into a string again before using it
Create your own type with a String() method, which is an integer but is represented by its hexadecimal value when printed.
For the second option, your type could be something like this:
type Hex int16
func (h Hex) String() string {
return strconv.FormatInt(int64(h), 16)
}
fmt.Println will automatically use this method because it means the Hex type implements the Stringer interface. For more info on this, here are some resources:
https://tour.golang.org/methods/17
https://golang.org/pkg/fmt/#Stringer

Related

Scramble/unscramble an integer value to/from hexadecimal string

I'm attempting to implement some Go code to solve a problem in which I need to sufficiently obfuscate a known integer value by converting it into a seemingly random hexadecimal string, when provided a known key value as an additional input parameter. The resulting hexadecimal string needs to always be the same number of characters in length (ideally, <= 32 characters).
Furthermore, using the same key string value, I need to un-obfuscate the hexadecimal string back into the original integer. For additional context, I'd like to satisfy the following function signatures (but am open to alternative methods, if necessary):
func Scramble(key string, value int32) string {
// TODO: Given a known key and value, generate a sufficiently unpredictable hexadecimal string.
}
func Unscramble(key string, value string) int32 {
// TODO: Given a known key and value, generate the integer that created the hexadecimal string.
}
func main() {
key := "Something super secret!"
scrambled := Scramble(key, 135)
fmt.Printf("Scrambled: %s\n", scrambled) // Scrambled: a1dec128b590b9ec3281110d6d188c26
unscrambled := Unscramble(key, scrambled)
fmt.Printf("Unscrambled: %d\n", unscrambled) // Unscrambled: 135
}
I think XOR'ing may be the right direction, but I'm unsure and not particularly familiar with the topic yet.
Any insight/direction would be greatly appreciated! Please let me know if I can provide any additional context/clarifications.
There are many native or external packages to achieve what you want, but if you want to implement this yourself for a learning experience, you can try the following tack:
Rather than shuffle your data back and forth between string and int32 format - keep the data in its raw type and use Stringer methods to convert to hex - and helper methods/functions to convert to the desired type. This simplifies the scrambling/unscrambling logic - as the input types are the same for both.
// Code custom type so we can add stringer methods
type Code uint32
// String converts code to hex string format
func (c Code) String() string {
return fmt.Sprintf("%x", uint32(c))
}
// CodeFromString gets a code from a hex string
func CodeFromString(hexs string) (Code, error) {
ui, err := strconv.ParseUint(hexs, 16, 32)
if err != nil {
return 0, err
}
return Code(ui), nil
}
// XOR scrambles/unscrambles
func XOR(key, value Code) Code {
return key ^ value
}
And to use:
keyHex := "74490a85"
valueHex := "d195c729"
value, _ := CodeFromString(valueHex)
key, _ := CodeFromString(keyHex)
scrambled := XOR(key, value)
unscrambled := XOR(key, scrambled)
Playground Example: https://play.golang.org/p/y5pbac_f8Z1

How to convert uint8 slice to string

What's the best way to convert from []uint8 to string?
I'm using http://github.com/confluentinc/confluent-kafka-go/kafka
To read events from kafka. But it does not return plain string event.
It returns event with type []uint8.
How can I convert this event from []uint8 to string?
byte is an alias for uint8, which means that a slice of uint8) (aka []uint8) is also a slice of byte (aka []byte).
And byte slices and strings are directly convertible, due to the fact that strings are backed by byte slices:
myByteSlice := []byte{ ... } // same as myByteSlice := []uint8{ ... }
myString := string(myByteSlice) // myString is a string representation of the byte slice
myOtherSlice := []byte(myString) // Converted back to byte slice

how to convert a string slice to rune slice

how can I convert type []string to []rune?
I know you can do it like this:
[]rune(strings.Join(array,""))
but is there a better way?
I would prefer not to use strings.Join(array,"") for this purpose because it builds one big new string I don't need. Making a big string I don't need is not space-efficient, and depending on input and hardware it may not be time-efficient.
So instead I would iterate through the array of string values and convert each string to a rune slice, and use the built-in variadic append function to grow my slice of all rune values:
var allRunes []rune
for _, str := range array {
allRunes = append(allRunes, []rune(str)...)
}

golang how does the rune() function work

I came across a function posted online that used the rune() function in golang, but I am having a hard time looking up what it is. I am going through the tutorial and inexperienced with the docs so it is hard to find what I am looking for.
Specifically, I am trying to see why this fails...
fmt.Println(rune("foo"))
and this does not
fmt.Println([]rune("foo"))
rune is a type in Go. It's just an alias for int32, but it's usually used to represent Unicode points. rune() isn't a function, it's syntax for type conversion into rune. Conversions in Go always have the syntax type() which might make them look like functions.
The first bit of code fails because conversion of strings to numeric types isn't defined in Go. However conversion of strings to slices of runes/int32s is defined like this in language specification:
Converting a value of a string type to a slice of runes type yields a
slice containing the individual Unicode code points of the string.
[golang.org]
So your example prints a slice of runes with values 102, 111 and 111
As stated in #Michael's first-rate comment fmt.Println([]rune("foo")) is a conversion of a string to a slice of runes []rune. When you convert from string to []rune, each utf-8 char in that string becomes a Rune. See https://stackoverflow.com/a/51611567/12817546. Similarly, in the reverse conversion, when converted from []rune to string, each rune becomes a utf-8 char in the string. See https://stackoverflow.com/a/51611567/12817546. A []rune can also be set to a byte, float64, int or a bool.
package main
import (
. "fmt"
)
func main() {
r := []rune("foo")
c := []interface{}{byte(r[0]), float64(r[0]), int(r[0]), r, string(r), r[0] != 0}
checkType(c)
}
func checkType(s []interface{}) {
for k, _ := range s {
Printf("%T %v\n", s[k], s[k])
}
}
byte(r[0]) is set to “uint8 102”, float64(r[0]) is set to “float64 102”,int(r[0]) is set to “int 102”, r is the rune” []int32 [102 111 111]”, string(r) prints “string foo”, r[0] != 0 and shows “bool true”.
[]rune to string conversion is supported natively by the spec. See the comment in https://stackoverflow.com/a/46021588/12817546. In Go then a string is a sequence of bytes. However, since multiple bytes can represent a rune code-point, a string value can also contain runes. So, it can be converted to a []rune , or vice versa. See https://stackoverflow.com/a/19325804/12817546.
Note, there are only two built-in type aliases in Go, byte (alias of uint8) and rune (alias of int32). See https://Go101.org/article/type-system-overview.html. Rune literals are just 32-bit integer values. For example, the rune literal 'a' is actually the number "97". See https://stackoverflow.com/a/19311218/12817546. Quotes edited.

Converting a []byte containing strings into decimal values

I am trying to take a string and convert each value in the string into the decimal ASCII value. I first converted the string into the []byte type and i want to take each element of the []byte and convert it into decimal ASCII value. Here is my code:
myArray := []byte(password) // convert string into []byte type
NumArray := [len(password)]int // create second []int type to store the converted []byte elements
for i := 0; i < len(myArray); i++{
/* I need some help to convert each element in myArray into ASCII decimal value and then store it into
NumArray.
*/
fmt.Printf("%d\n", myArray[i]) //prints out what the converted values should be
fmt.Print(NumArray[i]) //prints out the stored converted value for comparison
}
Edit: the string is supposed to be a password and so can contain any value
You can cast byte to int like this:
NumArray[i] = int(myArray[i])

Resources