Last active
April 1, 2024 13:14
-
-
Save quenbyako/bbd83cf4aa821b92892740037f7cbb7d to your computer and use it in GitHub Desktop.
How to get all characters in golang unicode range table
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// link to go playground: https://play.golang.org/p/BihbZqsk5Kh | |
package main | |
import ( | |
"crypto/rand" | |
"math/big" | |
"unicode" | |
) | |
func main() { | |
println(string(getAllChars(unicode.ASCII_Hex_Digit))) | |
println(string(getRandomChar(unicode.ASCII_Hex_Digit))) | |
} | |
func getAllChars(table *unicode.RangeTable) []rune { | |
res := make([]rune, 0) | |
for _, r := range table.R16 { | |
for c := r.Lo; c <= r.Hi; c += r.Stride { | |
res = append(res, rune(c)) | |
} | |
} | |
for _, r := range table.R32 { | |
for c := r.Lo; c <= r.Hi; c += r.Stride { | |
res = append(res, rune(c)) | |
} | |
} | |
return res | |
} | |
// maybe you can optimize it, but these are just unicode tricks | |
func getRandomChar(table *unicode.RangeTable) rune { | |
charsSum := getCharsCount(table) | |
choosed, err := rand.Int(rand.Reader, big.NewInt(int64(charsSum))) | |
if err != nil { | |
panic(err) | |
} | |
return getNChar(table, int(choosed.Int64())) | |
} | |
func getNChar(table *unicode.RangeTable, i int) rune { | |
for _, r := range table.R16 { | |
if i >= charsInR16(r) { | |
i -= charsInR16(r) | |
} else { | |
return rune(r.Lo + r.Stride*uint16(i)) | |
} | |
} | |
for _, r := range table.R32 { | |
if i >= charsInR32(r) { | |
i -= charsInR32(r) | |
} else { | |
return rune(r.Lo + r.Stride*uint32(i)) | |
} | |
} | |
panic("can't get here") | |
} | |
func getCharsCount(table *unicode.RangeTable) int { | |
var charsSum int | |
for _, r := range table.R16 { | |
charsSum += charsInR16(r) | |
} | |
for _, r := range table.R32 { | |
charsSum += charsInR32(r) | |
} | |
return charsSum | |
} | |
func charsInR16(r unicode.Range16) int { | |
return int((r.Hi-r.Lo)/r.Stride + 1) | |
} | |
func charsInR32(r unicode.Range32) int { | |
return int((r.Hi-r.Lo)/r.Stride + 1) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment