How to implement slowEqual with golang - go

I tried to implement a slowEqual with golang,but xor operation is limited to int and int8 and I have no idea to convert string to int[] or int8[] , even it can be converted it seems little awkward, and I found bytes.Equal but it seems not a slowEqual implementation.Any advices?
This is my impletation.
//TODO real slow equal
func slowEquals(a, b string) bool {
al := len(a)
bl := len(b)
aInts := make([]int, al)
bInts := make([]int, bl)
for i := 0; i < al; i++ {
aInts[i] = int(a[i])
}
for i := 0; i < bl; i++ {
bInts[i] = int(b[i])
}
var diff uint8 = uint8(al ^ bl)
for i := 0; i < al && i < bl; i++ {
diff |= a[i] ^ b[i]
}
return diff == 0
//长度相等为0
/*
abytes := []int8()
bbytes := []int8()
al := len(a)
bl := len(b)
diff := al ^ bl
for i := 0; i < al && i < bl; i++ {
diff |= a[i] ^ b[i]
}
return diff == 0
*/
}
Or:(after first answer)
import "crypto/subtle"
func SlowEquals(a, b string) bool {
if len(a) != len(b) {
return subtle.ConstantTimeCompare([]byte(a), make([]byte,len(a))) == 1
}else{
return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1
}
}

Perhaps this:
import "crypto/subtle"
func SlowEquals(a, b string) bool {
if len(a) != len(b) {
return false
}
return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1
}
This returns quickly if the lengths are different, but there's a timing attack against the original code that reveals the length of a, so I think this isn't worse.

Related

Mapping bits to int

I'm trying to map a uint64 array bit positions to an int array (see below). BitSet is a []uint64. Below is my code as currently setup. But I am wondering if there could be a std function in golang that can reduce this code. Other language has BitArray or other objects that makes life much easier.
So, in golang, do we have to code this? is there a better to do this?
// Indexes the index positions of '1' bits as an int array
func (b BitSet) Indexes() []int {
// set up masks for bit ANDing
masks := make([]uint64, _BitsPerUint64)
for i := 0; i < _BitsPerUint64; i++ {
masks[i] = (1 << uint(i))
}
// iterate bitset
indexes := make([]int, 0, len(b)*4)
for i := 0; i < len(b); i++ {
for m := 0; m < _BitsPerUint64; m++ {
if masks[m]&b[i] > 0 {
indexes = append(indexes, i*_BitsPerUint64+m)
}
}
}
return indexes
}
func (b BitSet) Indexes() []int {
retval := make([]int, 0, len(b)*64)
for idx, value := range b {
for i := 0; i < 64; i++ {
if value & (1<<uint(i)) != 0 {
retval = append(retval, idx*64 + i)
}
}
}
return retval
}

generate combinations/permutation of specific length

The project is more complex but the blocking issue is: How to generate a sequence of words of specific length from a list?
I've found how to generate all the possible combinations(see below) but the issue is that I need only the combinations of specific length.
Wolfram working example (it uses permutations though, I need only combinations(order doesn't matter)) :
Permutations[{a, b, c, d}, {3}]
Example(pseudo go):
list := []string{"alice", "moon", "walks", "mars", "sings", "guitar", "bravo"}
var premutationOf3
premutationOf3 = premuate(list, 3)
// this should return a list of all premutations such
// [][]string{[]string{"alice", "walks", "moon"}, []string{"alice", "signs", "guitar"} ....}
Current code to premutate all the possible sequences (no length limit)
for _, perm := range permutations(list) {
fmt.Printf("%q\n", perm)
}
func permutations(arr []string) [][]string {
var helper func([]string, int)
res := [][]string{}
helper = func(arr []string, n int) {
if n == 1 {
tmp := make([]string, len(arr))
copy(tmp, arr)
res = append(res, tmp)
} else {
for i := 0; i < n; i++ {
helper(arr, n-1)
if n%2 == 1 {
tmp := arr[i]
arr[i] = arr[n-1]
arr[n-1] = tmp
} else {
tmp := arr[0]
arr[0] = arr[n-1]
arr[n-1] = tmp
}
}
}
}
helper(arr, len(arr))
return res
}
I implement twiddle algorithm for generating combination in Go. Here is my implementation:
package twiddle
// Twiddle type contains all information twiddle algorithm
// need between each iteration.
type Twiddle struct {
p []int
b []bool
end bool
}
// New creates new twiddle algorithm instance
func New(m int, n int) *Twiddle {
p := make([]int, n+2)
b := make([]bool, n)
// initiate p
p[0] = n + 1
var i int
for i = 1; i != n-m+1; i++ {
p[i] = 0
}
for i != n+1 {
p[i] = i + m - n
i++
}
p[n+1] = -2
if m == 0 {
p[1] = 1
}
// initiate b
for i = 0; i != n-m; i++ {
b[i] = false
}
for i != n {
b[i] = true
i++
}
return &Twiddle{
p: p,
b: b,
}
}
// Next creates next combination and return it.
// it returns nil on end of combinations
func (t *Twiddle) Next() []bool {
if t.end {
return nil
}
r := make([]bool, len(t.b))
for i := 0; i < len(t.b); i++ {
r[i] = t.b[i]
}
x, y, end := t.twiddle()
t.b[x] = true
t.b[y] = false
t.end = end
return r
}
func (t *Twiddle) twiddle() (int, int, bool) {
var i, j, k int
var x, y int
j = 1
for t.p[j] <= 0 {
j++
}
if t.p[j-1] == 0 {
for i = j - 1; i != 1; i-- {
t.p[i] = -1
}
t.p[j] = 0
x = 0
t.p[1] = 1
y = j - 1
} else {
if j > 1 {
t.p[j-1] = 0
}
j++
for t.p[j] > 0 {
j++
}
k = j - 1
i = j
for t.p[i] == 0 {
t.p[i] = -1
i++
}
if t.p[i] == -1 {
t.p[i] = t.p[k]
x = i - 1
y = k - 1
t.p[k] = -1
} else {
if i == t.p[0] {
return x, y, true
}
t.p[j] = t.p[i]
t.p[i] = 0
x = j - 1
y = i - 1
}
}
return x, y, false
}
you can use my tweedle package as follow:
tw := tweedle.New(1, 2)
for b := tw.Next(); b != nil; b = tw.Next() {
fmt.Println(b)
}

Generate combinations from a given range

I'm trying to create a program capable to generate combinations from a given range.
I started editing this code below that generates combinations:
package main
import "fmt"
func nextPassword(n int, c string) func() string {
r := []rune(c)
p := make([]rune, n)
x := make([]int, len(p))
return func() string {
p := p[:len(x)]
for i, xi := range x {
p[i] = r[xi]
}
for i := len(x) - 1; i >= 0; i-- {
x[i]++
if x[i] < len(r) {
break
}
x[i] = 0
if i <= 0 {
x = x[0:0]
break
}
}
return string(p)
}
}
func main() {
np := nextPassword(2, "ABCDE")
for {
pwd := np()
if len(pwd) == 0 {
break
}
fmt.Println(pwd)
}
}
This is the Output of the code:
AA
AB
AC
AD
AE
BA
BB
BC
BD
BE
CA
CB
CC
CD
CE
DA
DB
DC
DD
DE
EA
EB
EC
ED
EE
And this is the code I edited:
package main
import "fmt"
const (
Min = 5
Max = 10
)
func nextPassword(n int, c string) func() string {
r := []rune(c)
p := make([]rune, n)
x := make([]int, len(p))
return func() string {
p := p[:len(x)]
for i, xi := range x {
p[i] = r[xi]
}
for i := len(x) - 1; i >= 0; i-- {
x[i]++
if x[i] < len(r) {
break
}
x[i] = 0
if i <= 0 {
x = x[0:0]
break
}
}
return string(p)
}
}
func main() {
cont := 0
np := nextPassword(2, "ABCDE")
for {
pwd := np()
if len(pwd) == 0 {
break
}
if cont >= Min && cont <= Max{
fmt.Println(pwd)
} else if cont > Max{
break
}
cont += 1
}
}
Output:
BA
BB
BC
BD
BE
CA
My code works, but if I increase the length of the combination and my range starts from the middle, the program will generate even the combinations that I don't want (and of course that will take a lot of time).
How can I solve this problem?
I really didn't like how nextPassword was written, so I made a variation. Rather than starting at 0 and repeatedly returning the next value, this one takes an integer and converts it to the corresponding "password." E.g. toPassword(0, 2, []rune("ABCDE")) is AA, and toPassword(5, ...) is BA.
From there, it's easy to loop over whatever range you want. But I also wrote a nextPassword wrapper around it that behaves similarly to the one in the original code. This one uses toPassword under the cover and takes a starting n.
Runnable version here: https://play.golang.org/p/fBo6mx4Mji
Code below:
package main
import (
"fmt"
)
func toPassword(n, length int, alphabet []rune) string {
base := len(alphabet)
// This will be our output
result := make([]rune, length)
// Start filling from the right
i := length - 1
// This is essentially a conversion to base-b, where b is
// the number of possible letters (5 in the case of "ABCDE")
for n > 0 {
// Filling from the right, put the right digit mod b
result[i] = alphabet[n%base]
// Divide the number by the base so we're ready for
// the next digit
n /= base
// Move to the left
i -= 1
}
// Fill anything that's left with "zeros" (first letter of
// the alphabet)
for i >= 0 {
result[i] = alphabet[0]
i -= 1
}
return string(result)
}
// Convenience function that just returns successive values from
// toPassword starting at start
func nextPassword(start, length int, alphabet []rune) func() string {
n := start
return func() string {
result := toPassword(n, length, alphabet)
n += 1
return result
}
}
func main() {
for i := 5; i < 11; i++ {
fmt.Println(toPassword(i, 2, []rune("ABCDE")))
} // BA, BB, BC, BD, BE, CA
// Now do the same thing using nextPassword
np := nextPassword(5, 2, []rune("ABCDE"))
for i := 0; i < 6; i++ {
fmt.Println(np())
} // BA, BB, BC, BD, BE, CA
}

Go : longest common subsequence to print result array

I have implemented Longest Common Subsequence algorithm and getting the right answer for longest but cannot figure out the way to print out what makes up the longest common subsequence.
That is, I succeeded to get the length of longest commond subsequence array but I want to print out the longest subsequence.
The Playground for this code is here
http://play.golang.org/p/0sKb_OARnf
/*
X = BDCABA
Y = ABCBDAB => Longest Comman Subsequence is B C B
Dynamic Programming method : O ( n )
*/
package main
import "fmt"
func Max(more ...int) int {
max_num := more[0]
for _, elem := range more {
if max_num < elem {
max_num = elem
}
}
return max_num
}
func Longest(str1, str2 string) int {
len1 := len(str1)
len2 := len(str2)
//in C++,
//int tab[m + 1][n + 1];
//tab := make([][100]int, len1+1)
tab := make([][]int, len1+1)
for i := range tab {
tab[i] = make([]int, len2+1)
}
i, j := 0, 0
for i = 0; i <= len1; i++ {
for j = 0; j <= len2; j++ {
if i == 0 || j == 0 {
tab[i][j] = 0
} else if str1[i-1] == str2[j-1] {
tab[i][j] = tab[i-1][j-1] + 1
if i < len1 {
fmt.Printf("%c", str1[i])
}
} else {
tab[i][j] = Max(tab[i-1][j], tab[i][j-1])
}
}
}
fmt.Println()
return tab[len1][len2]
}
func main() {
str1 := "AGGTABTABTABTAB"
str2 := "GXTXAYBTABTABTAB"
fmt.Println(Longest(str1, str2))
//Actual Longest Common Subsequence: GTABTABTABTAB
//GGGGGTAAAABBBBTTTTAAAABBBBTTTTAAAABBBBTTTTAAAABBBB
//13
str3 := "AGGTABGHSRCBYJSVDWFVDVSBCBVDWFDWVV"
str4 := "GXTXAYBRGDVCBDVCCXVXCWQRVCBDJXCVQSQQ"
fmt.Println(Longest(str3, str4))
//Actual Longest Common Subsequence: ?
//GGGTTABGGGHHRCCBBBBBBYYYJSVDDDDDWWWFDDDDDVVVSSSSSBCCCBBBBBBVVVDDDDDWWWFWWWVVVVVV
//14
}
When I try to print out the subsequence when the tab gets updates, the outcome is duplicate.
I want to print out something like "GTABTABTABTAB" for the str1 and str2
Thanks in advance.
EDIT: It seems that I jumped the gun on answering this. On the Wikipedia page for Longest Common Subsequnce they give the pseudocode for printing out the LCS once it has been calculated. I'll put an implementation in go up here as soon as I have time for it.
Old invalid answer
You are forgetting to move along from a character once you have registered it as part of the subsequence.
The code below should work. Look at the two lines right after the fmt.Printf("%c", srt1[i]) line.
playground link
/*
X = BDCABA
Y = ABCBDAB => Longest Comman Subsequence is B C B
Dynamic Programming method : O ( n )
*/
package main
import "fmt"
func Max(more ...int) int {
max_num := more[0]
for _, elem := range more {
if max_num < elem {
max_num = elem
}
}
return max_num
}
func Longest(str1, str2 string) int {
len1 := len(str1)
len2 := len(str2)
//in C++,
//int tab[m + 1][n + 1];
//tab := make([][100]int, len1+1)
tab := make([][]int, len1+1)
for i := range tab {
tab[i] = make([]int, len2+1)
}
i, j := 0, 0
for i = 0; i <= len1; i++ {
for j = 0; j <= len2; j++ {
if i == 0 || j == 0 {
tab[i][j] = 0
} else if str1[i-1] == str2[j-1] {
tab[i][j] = tab[i-1][j-1] + 1
if i < len1 {
fmt.Printf("%c", str1[i])
//Move on the the next character in both sequences
i++
j++
}
} else {
tab[i][j] = Max(tab[i-1][j], tab[i][j-1])
}
}
}
fmt.Println()
return tab[len1][len2]
}
func main() {
str1 := "AGGTABTABTABTAB"
str2 := "GXTXAYBTABTABTAB"
fmt.Println(Longest(str1, str2))
//Actual Longest Common Subsequence: GTABTABTABTAB
//GGGGGTAAAABBBBTTTTAAAABBBBTTTTAAAABBBBTTTTAAAABBBB
//13
str3 := "AGGTABGHSRCBYJSVDWFVDVSBCBVDWFDWVV"
str4 := "GXTXAYBRGDVCBDVCCXVXCWQRVCBDJXCVQSQQ"
fmt.Println(Longest(str3, str4))
//Actual Longest Common Subsequence: ?
//GGGTTABGGGHHRCCBBBBBBYYYJSVDDDDDWWWFDDDDDVVVSSSSSBCCCBBBBBBVVVDDDDDWWWFWWWVVVVVV
//14
}

How to compare two version number strings in golang

I have two strings (they are actually version numbers and they could be any version numbers)
a := "1.05.00.0156"
b := "1.0.221.9289"
I want to compare which one is bigger. How to do it in golang?
There is a nice solution from Hashicorp - https://github.com/hashicorp/go-version
import github.com/hashicorp/go-version
v1, err := version.NewVersion("1.2")
v2, err := version.NewVersion("1.5+metadata")
// Comparison example. There is also GreaterThan, Equal, and just
// a simple Compare that returns an int allowing easy >=, <=, etc.
if v1.LessThan(v2) {
fmt.Printf("%s is less than %s", v1, v2)
}
Some time ago I created a version comparison library: https://github.com/mcuadros/go-version
version.CompareSimple("1.05.00.0156", "1.0.221.9289")
//Returns: 1
Enjoy it!
Here's a general solution.
package main
import "fmt"
func VersionOrdinal(version string) string {
// ISO/IEC 14651:2011
const maxByte = 1<<8 - 1
vo := make([]byte, 0, len(version)+8)
j := -1
for i := 0; i < len(version); i++ {
b := version[i]
if '0' > b || b > '9' {
vo = append(vo, b)
j = -1
continue
}
if j == -1 {
vo = append(vo, 0x00)
j = len(vo) - 1
}
if vo[j] == 1 && vo[j+1] == '0' {
vo[j+1] = b
continue
}
if vo[j]+1 > maxByte {
panic("VersionOrdinal: invalid version")
}
vo = append(vo, b)
vo[j]++
}
return string(vo)
}
func main() {
versions := []struct{ a, b string }{
{"1.05.00.0156", "1.0.221.9289"},
// Go versions
{"1", "1.0.1"},
{"1.0.1", "1.0.2"},
{"1.0.2", "1.0.3"},
{"1.0.3", "1.1"},
{"1.1", "1.1.1"},
{"1.1.1", "1.1.2"},
{"1.1.2", "1.2"},
}
for _, version := range versions {
a, b := VersionOrdinal(version.a), VersionOrdinal(version.b)
switch {
case a > b:
fmt.Println(version.a, ">", version.b)
case a < b:
fmt.Println(version.a, "<", version.b)
case a == b:
fmt.Println(version.a, "=", version.b)
}
}
}
Output:
1.05.00.0156 > 1.0.221.9289
1 < 1.0.1
1.0.1 < 1.0.2
1.0.2 < 1.0.3
1.0.3 < 1.1
1.1 < 1.1.1
1.1.1 < 1.1.2
1.1.2 < 1.2
go-semver is a semantic versioning library for Go. It lets you parse and compare two semantic version strings.
Example:
vA := semver.New("1.2.3")
vB := semver.New("3.2.1")
fmt.Printf("%s < %s == %t\n", vA, vB, vA.LessThan(*vB))
Output:
1.2.3 < 3.2.1 == true
Here are some of the libraries for version comparison:
https://github.com/blang/semver
https://github.com/Masterminds/semver
https://github.com/hashicorp/go-version
https://github.com/mcuadros/go-version
I have used blang/semver.
Eg: https://play.golang.org/p/1zZvEjLSOAr
import github.com/blang/semver/v4
v1, err := semver.Make("1.0.0-beta")
v2, err := semver.Make("2.0.0-beta")
// Options availabe
v1.Compare(v2) // Compare
v1.LT(v2) // LessThan
v1.GT(v2) // GreaterThan
This depends on what you mean by bigger.
A naive approach would be:
package main
import "fmt"
import "strings"
func main() {
a := strings.Split("1.05.00.0156", ".")
b := strings.Split("1.0.221.9289", ".")
for i, s := range a {
var ai, bi int
fmt.Sscanf(s, "%d", &ai)
fmt.Sscanf(b[i], "%d", &bi)
if ai > bi {
fmt.Printf("%v is bigger than %v\n", a, b)
break
}
if bi > ai {
fmt.Printf("%v is bigger than %v\n", b, a)
break
}
}
}
http://play.golang.org/p/j0MtFcn44Z
Based on Jeremy Wall's answer:
func compareVer(a, b string) (ret int) {
as := strings.Split(a, ".")
bs := strings.Split(b, ".")
loopMax := len(bs)
if len(as) > len(bs) {
loopMax = len(as)
}
for i := 0; i < loopMax; i++ {
var x, y string
if len(as) > i {
x = as[i]
}
if len(bs) > i {
y = bs[i]
}
xi,_ := strconv.Atoi(x)
yi,_ := strconv.Atoi(y)
if xi > yi {
ret = -1
} else if xi < yi {
ret = 1
}
if ret != 0 {
break
}
}
return
}
http://play.golang.org/p/AetJqvFc3B
Striving for clarity and simplicity:
func intVer(v string) (int64, error) {
sections := strings.Split(v, ".")
intVerSection := func(v string, n int) string {
if n < len(sections) {
return fmt.Sprintf("%04s", sections[n])
} else {
return "0000"
}
}
s := ""
for i := 0; i < 4; i++ {
s += intVerSection(v, i)
}
return strconv.ParseInt(s, 10, 64)
}
func main() {
a := "3.045.98.0832"
b := "087.2345"
va, _ := intVer(a)
vb, _ := intVer(b)
fmt.Println(va<vb)
}
Comparing versions implies parsing so I believe these 2 steps should be separate to make it robust.
tested in leetcode: https://leetcode.com/problems/compare-version-numbers/
func compareVersion(version1 string, version2 string) int {
len1, len2, i, j := len(version1), len(version2), 0, 0
for i < len1 || j < len2 {
n1 := 0
for i < len1 && '0' <= version1[i] && version1[i] <= '9' {
n1 = n1 * 10 + int(version1[i] - '0')
i++
}
n2 := 0
for j < len2 && '0' <= version2[j] && version2[j] <= '9' {
n2 = n2 * 10 + int(version2[j] - '0')
j++
}
if n1 > n2 {
return 1
}
if n1 < n2 {
return -1
}
i, j = i+1, j+1
}
return 0
}
import (
"fmt"
"strconv"
"strings"
)
func main() {
j := ll("1.05.00.0156" ,"1.0.221.9289")
fmt.Println(j)
}
func ll(a,b string) int {
var length ,r,l int = 0,0,0
v1 := strings.Split(a,".")
v2 := strings.Split(b,".")
len1, len2 := len(v1), len(v2)
length = len2
if len1 > len2 {
length = len1
}
for i:= 0;i<length;i++ {
if i < len1 && i < len2 {
if v1[i] == v2[i] {
continue
}
}
r = 0
if i < len1 {
if number, err := strconv.Atoi(v1[i]); err == nil {
r = number
}
}
l = 0
if i < len2 {
if number, err := strconv.Atoi(v2[i]); err == nil {
l = number
}
}
if r < l {
return -1
}else if r> l {
return 1
}
}
return 0
}
If you can guarantee version strings have same format (i.e. SemVer), you can convert to int and compare int. Here is an implementation for sorting slices of SemVer:
versions := []string{"1.0.10", "1.0.6", "1.0.9"}
sort.Slice(versions[:], func(i, j int) bool {
as := strings.Split(versions[i], ".")
bs := strings.Split(versions[j], ".")
if len(as) != len(bs) || len(as) != 3 {
return versions[i] < versions[j]
}
ais := make([]int, len(as))
bis := make([]int, len(bs))
for i := range as {
ais[i], _ = strconv.Atoi(as[i])
bis[i], _ = strconv.Atoi(bs[i])
}
//X.Y.Z
// If X and Y are the same, compare Z
if ais[0] == bis[0] && ais[1] == bis[1] {
return ais[2] < bis[2]
}
// If X is same, compare Y
if ais[0] == bis[0] {
return ais[1] < bis[1]
}
// Compare X
return ais[0] < bis[0]
})
fmt.Println(versions)
tested in go playground
// If v1 > v2 return '>'
// If v1 < v2 return '<'
// Otherwise return '='
func CompareVersion(v1, v2 string) byte {
v1Slice := strings.Split(v1, ".")
v2Slice := strings.Split(v2, ".")
var maxSize int
{ // Make them both the same size.
if len(v1Slice) < len(v2Slice) {
maxSize = len(v2Slice)
} else {
maxSize = len(v1Slice)
}
}
v1NSlice := make([]int, maxSize)
v2NSlice := make([]int, maxSize)
{
// Convert string to the int.
for i := range v1Slice {
v1NSlice[i], _ = strconv.Atoi(v1Slice[i])
}
for i := range v2Slice {
v2NSlice[i], _ = strconv.Atoi(v2Slice[i])
}
}
var result byte
var v2Elem int
for i, v1Elem := range v1NSlice {
if result != '=' && result != 0 { // The previous comparison has got the answer already.
return result
}
v2Elem = v2NSlice[i]
if v1Elem > v2Elem {
result = '>'
} else if v1Elem < v2Elem {
result = '<'
} else {
result = '='
}
}
return result
}
Convert "1.05.00.0156" to "0001"+"0005"+"0000"+"0156", then to int64.
Convert "1.0.221.9289" to "0001"+"0000"+"0221"+"9289", then to int64.
Compare the two int64 values.
Try it on the Go playground

Resources