diff options
Diffstat (limited to 'Base58.hs')
-rw-r--r-- | Base58.hs | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/Base58.hs b/Base58.hs new file mode 100644 index 0000000..26f1cb2 --- /dev/null +++ b/Base58.hs | |||
@@ -0,0 +1,37 @@ | |||
1 | module Base58 where | ||
2 | |||
3 | import qualified Crypto.Hash.SHA256 as SHA256 | ||
4 | import qualified Data.ByteString as S | ||
5 | import Data.Maybe | ||
6 | import Data.List | ||
7 | import Data.Word ( Word8 ) | ||
8 | import Control.Monad | ||
9 | |||
10 | base58chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" | ||
11 | |||
12 | base58digits :: [Char] -> Maybe [Int] | ||
13 | base58digits str = sequence mbs | ||
14 | where | ||
15 | mbs = map (flip elemIndex base58chars) str | ||
16 | |||
17 | -- 5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ | ||
18 | base58_decode :: [Char] -> Maybe (Word8,[Word8]) | ||
19 | base58_decode str = do | ||
20 | ds <- base58digits str | ||
21 | let n = foldl' (\a b-> a*58 + b) 0 $ ( map fromIntegral ds :: [Integer] ) | ||
22 | rbytes = unfoldr getbyte n | ||
23 | getbyte d = do | ||
24 | guard (d/=0) | ||
25 | let (q,b) = d `divMod` 256 | ||
26 | return (fromIntegral b,q) | ||
27 | |||
28 | let (rcksum,rpayload) = splitAt 4 $ rbytes | ||
29 | a_payload = reverse rpayload | ||
30 | hash_result = S.take 4 . SHA256.hash . SHA256.hash . S.pack $ a_payload | ||
31 | expected_hash = S.pack $ reverse rcksum | ||
32 | (network_id,payload) = splitAt 1 a_payload | ||
33 | |||
34 | network_id <- listToMaybe network_id | ||
35 | guard (hash_result==expected_hash) | ||
36 | return (network_id,payload) | ||
37 | |||