Convert substring to int in golang - string

I have this variable:
danumber := "542353242"
and want to extract a character from the string and operate with it as a number.
Tried this:
int(danumber[0])
but it doesn't seem to work.

What your expression gives you is the character code for the digit. To convert the character to the character's value, subtract 0's character code from it:
int(danumber[0] - '0') // in your example, this is: 53 - 48
If you want to convert multiple digits, I would recommend using the strconv package:
number, err := strconv.Atoi(danumber[0:2]) // convert first two characters to int

Related

Determine number length in a file in Twincat 3

I am reading a file on my computer that contains the following information:
cellcount=011 (INT)
currentdensity=1.112 (REAL)
REAL2=2.1145 (REAL)
INT1=41823 (INT)
REAL3=4.2023 (REAL)
INT=11 (INT)
Currently I am storing the ReadBuffer in a string(1000) because I thought that was the easiest way to manipulate the content. I want to be able to extract the numbers as you see and store them in variables. I want it to be dynamic so folks can enter any number (not reals in to ints, but otherwise).
so far I have looked at the string functions of twincat 3 and using MID() and FIND() I can make something work, but then I need to know the length of the numbers. Like this:
test.CellCount := STRING_TO_INT(MID(sTest,number_of_chars,FIND(sTest,'cellcount:')+10));
Any idea how to make this dynamic?
Square brackets after a string variable will allow you to extract the ASCII code of a particular character. Knowing that digits 0-9 are ASCII codes 48-57, you can iterate through the characters following your search string until no more digits are found. For example:
loc1 := FIND(sTest,'cellcount=') + 9;
FOR i:=loc1 TO (loc1+10) DO // 10 = maximum length of number
IF (sTest[i]>=48 AND sTest[i]<=57) OR sTest[i]=46 THEN
loc2 := i;
ELSE
EXIT;
END_IF
END_FOR
number_of_chars := loc2 - loc1 + 1;
ASCII code 46 is the decimal point, to allow parsing of floating point values.

How to convert integer to fixed length hex string in Go?

I want to convert an integer to a hex string with a fixed length of 64 characters, prepended with zeros for integer values that do not use up all 32 hex values. If I try the following it adds spaces in front of s rather than zeros.
i := 898757
s := fmt.Sprintf("%64x", i)
fmt.Println(s)
The correct format is "%064x":
fmt.Printf("%064x\n", 898757)
00000000000000000000000000000000000000000000000000000000000db6c5
Where the leading 0 is a "flag" for the formatting string. Per the fmt docs:
0: pad with leading zeros rather than spaces;
for numbers, this moves the padding after the sign
My personal preference is to use a period to separate the flags from the length field. This technically works because . is not meaningful with the integer verbs and is ignored. I find it a useful visual indicator. The format string becomes "%0.64x".

Convert an int to hex and then pad it with 0's to get a fixed length String

I'm having some issues on trying to convert an int to hex then, padding it with 0s in order to get a 6 Characters String which represents the hex number.
So far, I tried the following:
intNumber := 12
hexNumber := strconv.FormatInt(intNumber, 16) //not working
And then I found out how to pad it with 0s, using %06d, number/string. It makes all the strings 6 characters long.
Here you can Find a Playground which I set up to make some tests.
How can I achieve this in a efficient way?
For any Clarifications on the question, just leave a comment below.
Thanks In advance.
import "fmt"
hex := fmt.Sprintf("%06x", num)
The x means hexadecimal, the 6 means 6 digits, the 0 means left-pad with zeros and the % starts the whole sequence.

Output UUID in Go as a short string

Is there a built in way, or reasonably standard package that allows you to convert a standard UUID into a short string that would enable shorter URL's?
I.e. taking advantage of using a larger range of characters such as [A-Za-z0-9] to output a shorter string.
I know we can use base64 to encode the bytes, as follows, but I'm after something that creates a string that looks like a "word", i.e. no + and /:
id = base64.StdEncoding.EncodeToString(myUuid.Bytes())
A universally unique identifier (UUID) is a 128-bit value, which is 16 bytes. For human-readable display, many systems use a canonical format using hexadecimal text with inserted hyphen characters, for example:
123e4567-e89b-12d3-a456-426655440000
This has length 16*2 + 4 = 36. You may choose to omit the hypens which gives you:
fmt.Printf("%x\n", uuid)
fmt.Println(hex.EncodeToString(uuid))
// Output: 32 chars
123e4567e89b12d3a456426655440000
123e4567e89b12d3a456426655440000
You may choose to use base32 encoding (which encodes 5 bits with 1 symbol in contrast to hex encoding which encodes 4 bits with 1 symbol):
fmt.Println(base32.StdEncoding.EncodeToString(uuid))
// Output: 26 chars
CI7EKZ7ITMJNHJCWIJTFKRAAAA======
Trim the trailing = signs when transmitting, so this will always be 26 chars. Note that you have to append "======" prior to decode the string using base32.StdEncoding.DecodeString().
If this is still too long for you, you may use base64 encoding (which encodes 6 bits with 1 symbol):
fmt.Println(base64.RawURLEncoding.EncodeToString(uuid))
// Output: 22 chars
Ej5FZ-ibEtOkVkJmVUQAAA
Note that base64.RawURLEncoding produces a base64 string (without padding) which is safe for URL inclusion, because the 2 extra chars in the symbol table (beyond [0-9a-zA-Z]) are - and _, both which are safe to be included in URLs.
Unfortunately for you, the base64 string may contain 2 extra chars beyond [0-9a-zA-Z]. So read on.
Interpreted, escaped string
If you are alien to these 2 extra characters, you may choose to turn your base64 string into an interpreted, escaped string similar to the interpreted string literals in Go. For example if you want to insert a backslash in an interpreted string literal, you have to double it because backslash is a special character indicating a sequence, e.g.:
fmt.Println("One backspace: \\") // Output: "One backspace: \"
We may choose to do something similar to this. We have to designate a special character: be it 9.
Reasoning: base64.RawURLEncoding uses the charset: A..Za..z0..9-_, so 9 represents the highest code with alphanumeric character (61 decimal = 111101b). See advantage below.
So whenever the base64 string contains a 9, replace it with 99. And whenever the base64 string contains the extra characters, use a sequence instead of them:
9 => 99
- => 90
_ => 91
This is a simple replacement table which can be captured by a value of strings.Replacer:
var escaper = strings.NewReplacer("9", "99", "-", "90", "_", "91")
And using it:
fmt.Println(escaper.Replace(base64.RawURLEncoding.EncodeToString(uuid)))
// Output:
Ej5FZ90ibEtOkVkJmVUQAAA
This will slightly increase the length as sometimes a sequence of 2 chars will be used instead of 1 char, but the gain will be that only [0-9a-zA-Z] chars will be used, as you wanted. The average length will be less than 1 additional character: 23 chars. Fair trade.
Logic: For simplicity let's assume all possible uuids have equal probability (uuid is not completely random, so this is not the case, but let's set this aside as this is just an estimation). Last base64 symbol will never be a replaceable char (that's why we chose the special char to be 9 instead of like A), 21 chars may turn into a replaceable sequence. The chance for one being replaceable: 3 / 64 = 0.047, so on average this means 21*3/64 = 0.98 sequences which turn 1 char into a 2-char sequence, so this is equal to the number of extra characters.
To decode, use an inverse decoding table captured by the following strings.Replacer:
var unescaper = strings.NewReplacer("99", "9", "90", "-", "91", "_")
Example code to decode an escaped base64 string:
fmt.Println("Verify decoding:")
s := escaper.Replace(base64.RawURLEncoding.EncodeToString(uuid))
dec, err := base64.RawURLEncoding.DecodeString(unescaper.Replace(s))
fmt.Printf("%x, %v\n", dec, err)
Output:
123e4567e89b12d3a456426655440000, <nil>
Try all the examples on the Go Playground.
As suggested here, If you want just a fairly random string to use as slug, better to not bother with UUID at all.
You can simply use go's native math/rand library to make random strings of desired length:
import (
"math/rand"
"encoding/hex"
)
b := make([]byte, 4) //equals 8 characters
rand.Read(b)
s := hex.EncodeToString(b)
Another option is math/big. While base64 has a constant output of 22
characters, math/big can get down to 2 characters, depending on the input:
package main
import (
"encoding/base64"
"fmt"
"math/big"
)
type uuid [16]byte
func (id uuid) encode() string {
return new(big.Int).SetBytes(id[:]).Text(62)
}
func main() {
var id uuid
for n := len(id); n > 0; n-- {
id[n - 1] = 0xFF
s := base64.RawURLEncoding.EncodeToString(id[:])
t := id.encode()
fmt.Printf("%v %v\n", s, t)
}
}
Result:
AAAAAAAAAAAAAAAAAAAA_w 47
AAAAAAAAAAAAAAAAAAD__w h31
AAAAAAAAAAAAAAAAAP___w 18owf
AAAAAAAAAAAAAAAA_____w 4GFfc3
AAAAAAAAAAAAAAD______w jmaiJOv
AAAAAAAAAAAAAP_______w 1hVwxnaA7
AAAAAAAAAAAA_________w 5k1wlNFHb1
AAAAAAAAAAD__________w lYGhA16ahyf
AAAAAAAAAP___________w 1sKyAAIxssts3
AAAAAAAA_____________w 62IeP5BU9vzBSv
AAAAAAD______________w oXcFcXavRgn2p67
AAAAAP_______________w 1F2si9ujpxVB7VDj1
AAAA_________________w 6Rs8OXba9u5PiJYiAf
AAD__________________w skIcqom5Vag3PnOYJI3
AP___________________w 1SZwviYzes2mjOamuMJWv
_____________________w 7N42dgm5tFLK9N8MT7fHC7
https://golang.org/pkg/math/big

How can I convert a character code to a string character in Lua?

How can I convert a character code to a string character in Lua?
E.g.
d = 48
-- this is what I want
str_d = "0"
You are looking for string.char:
string.char (···)
Receives zero or more integers. Returns a string with length equal to the number of arguments, in which each character has the internal numerical code equal to its corresponding argument.
Note that numerical codes are not necessarily portable across platforms.
For your example:
local d = 48
local str_d = string.char(d) -- str_d == "0"
For ASCII characters, you can use string.char.
For UTF-8 strings, you can use utf8.char(introduced in Lua 5.3) to get a character from its code point.
print(utf8.char(48)) -- 0
print(utf8.char(29790)) -- 瑞

Resources