Created
October 8, 2019 21:08
-
-
Save tchap/ad3217508fcd560ccf48826e08f87cbe to your computer and use it in GitHub Desktop.
This improves https://offsec.almond.consulting/super-magic-hash.html
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
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