Skip to content

Instantly share code, notes, and snippets.

@tchap
Created October 8, 2019 21:08
Show Gist options
  • Save tchap/ba97d6e4bd7312e7f250cd49606aff59 to your computer and use it in GitHub Desktop.
Save tchap/ba97d6e4bd7312e7f250cd49606aff59 to your computer and use it in GitHub Desktop.
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"math/rand"
"regexp"
"testing"
"time"
)
var re = regexp.MustCompile(`^0+e\d*$`)
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&~#'{([-|_@)]=}+$*!:;,?./"
func hash_sha224(password string) string {
h := sha256.New224()
h.Write([]byte(password))
bs := h.Sum(nil)
hash := fmt.Sprintf("%x\n", bs)
return string(hash)
}
var src = rand.NewSource(time.Now().UnixNano())
const (
letterIdxBits = 6 // 6 bits to represent a letter index
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)
func rand_3(b []byte) {
n := len(b)
for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
if remain == 0 {
cache, remain = src.Int63(), letterIdxMax
}
if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
b[i] = letterBytes[idx]
i--
}
cache >>= letterIdxBits
remain--
}
}
func Parse_2(h []byte) bool {
if h[0] == 0 || h[0] == 14 { //check whether the hash starts by 00 or 0e
for _, x := range h[1:] {
switch x { //all unexpected bytes return false (https://ascii.cl/conversion.htm)
case
10, 11, 12, 13, 15, //0A to 0F
26, 27, 28, 29, 31, //1A to 1F
42, 43, 44, 45, 47, //2A to 2F
58, 59, 60, 61, 63, //3A to 3F
74, 75, 76, 77, 79, //4A to 4F
90, 91, 92, 93, 95, //5A to 5F
106, 107, 108, 109, 111, //6A to 6F
122, 123, 124, 125, 127, //7A to 7F
138, 139, 140, 141, 143, //8A to 8F
154, 155, 156, 157, 159, //9A to 9F
160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, //A0 to AF
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, //B0 to BF
192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, //C0 to CF
208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, //D0 to DF
234, 235, 236, 237, 238, 239, //EA to EF
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255: //F0 to FF
return false
}
}
} else {
return false
}
return true
}
// BenchmarkParse_6-4 10175305 561 ns/op 0 B/op 0 allocs/op
func BenchmarkParse_6(b *testing.B) {
h := sha256.New224()
r := make([]byte, 8)
sum := make([]byte, 0, 28)
for n := 0; n < b.N; n++ {
sum = sum[:0]
rand_3(r)
h.Reset()
h.Write(r)
sum = h.Sum(sum)
if Parse_2(sum) && re.FindString(hex.EncodeToString(sum)) != "" {
//Unexpected hashes like 0e0e34567890123456789012345678901234567890123456789012 could pass the Parse_3 function so for these rare cases we can use the slow regexp check
fmt.Println(string(r))
fmt.Println(hex.EncodeToString(sum))
fmt.Println("")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment