Last active
June 23, 2020 21:38
-
-
Save ear7h/4448880ed4ff20eac3110244dd64b854 to your computer and use it in GitHub Desktop.
geohash into 32 bits
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 ( | |
"fmt" | |
) | |
func main() { | |
geohash := "u4pruydqqvj" | |
for i := range geohash { | |
fmt.Println(geohash[:i+1], "\t", geohash2bits(geohash[:i+1])) | |
} | |
} | |
func geohash2bits(s string) int64 { | |
ret := int64(0) | |
byt := []byte(s) | |
// a single base32 character is 5 bits | |
// and our destination is the 63 least significant bits of an int64 | |
// so, we can fit 12 3/5 characters in the int | |
for i := 0; i < len(byt) && i < 12; i++ { | |
ret = (base32[byt[i]] << (i*5)) | ret | |
} | |
return ret | |
} | |
var base32 = [256]int64{ | |
'0': 0, | |
'1': 1, | |
'2': 2, | |
'3': 3, | |
'4': 4, | |
'5': 5, | |
'6': 6, | |
'7': 7, | |
'8': 8, | |
'9': 9, | |
'b': 10, | |
'c': 11, | |
'd': 12, | |
'e': 13, | |
'f': 14, | |
'g': 15, | |
'h': 16, | |
'j': 17, | |
'k': 18, | |
'm': 19, | |
'n': 20, | |
'p': 21, | |
'q': 22, | |
'r': 23, | |
's': 24, | |
't': 25, | |
'u': 26, | |
'v': 27, | |
'w': 28, | |
'x': 29, | |
'y': 30, | |
'z': 31, | |
} |
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
CREATE OR REPLACE FUNCTION base32_decode(IN hash text) RETURNS bigint AS $$ | |
DECLARE | |
tbl bigint[] := ARRAY[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 10, 11, 12, 13, 14, 15, 16, 0, 17, 18, 0, 19, 20, 0, | |
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; | |
ret bigint := 0; | |
it integer := 0; | |
BEGIN | |
-- a single base32 character is 5 bits | |
-- and our destination is the 63 least significant bits of and int64 | |
-- | |
-- so we can fit 12 3/5 characters in our destination. To prevent overflow | |
-- into the sign bit, we use 12 characters | |
WHILE it < LENGTH(hash) AND it < 12 LOOP | |
ret := (tbl[1+ASCII(SUBSTRING(hash, it+1, 1))] << (it * 5)) | ret; | |
it := it+1; | |
END LOOP; | |
RETURN ret; | |
END; | |
$$ LANGUAGE plpgsql IMMUTABLE; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment