summaryrefslogtreecommitdiff
path: root/Base58.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Base58.hs')
-rw-r--r--Base58.hs37
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 @@
1module Base58 where
2
3import qualified Crypto.Hash.SHA256 as SHA256
4import qualified Data.ByteString as S
5import Data.Maybe
6import Data.List
7import Data.Word ( Word8 )
8import Control.Monad
9
10base58chars = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
11
12base58digits :: [Char] -> Maybe [Int]
13base58digits str = sequence mbs
14 where
15 mbs = map (flip elemIndex base58chars) str
16
17-- 5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ
18base58_decode :: [Char] -> Maybe (Word8,[Word8])
19base58_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