Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -0,0 +1,53 @@
import Data.List (unfoldr, elemIndex)
import Data.Binary (Word8)
import Crypto.Hash.SHA256 (hash)
import Data.ByteString (unpack, pack)
-- Convert from base58 encoded value to Integer
decode58 :: String -> Maybe Integer
decode58 = foldl (\v d -> (+) <$> ((58*) <$> v) <*> (fromIntegral <$> elemIndex d c58 )) $ Just 0
where c58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
-- Convert from base58 encoded value to list of bytes
toBytes :: Integer -> [Word8]
toBytes x = reverse $ unfoldr (\b -> if b == 0 then Nothing else Just (fromIntegral $ b `mod` 256, b `div` 256)) x
-- Check validity of base58 encoded bitcoin address.
-- Result is either an error string (Left) or a validity bool (Right).
validityCheck :: String -> Either String Bool
validityCheck encodedAddress =
let d58 = decode58 encodedAddress
in case d58 of
Nothing -> Left "Invalid base 58 encoding"
Just ev ->
let address = toBytes ev
addressLength = length address
in if addressLength > 24
then Left "Address length exceeds 25 bytes"
else
if addressLength < 4
then Left "Address length less than 4 bytes"
else
let (bs,cs) = splitAt 21 $ replicate (25 - addressLength) 0 ++ address
in Right $ all (uncurry (==)) (zip cs $ unpack $ hash $ hash $ pack bs)
-- Run one validity check and display results.
validate :: String -> IO ()
validate encodedAddress =
let vc = validityCheck encodedAddress
in case vc of
Left err ->
putStrLn $ show encodedAddress ++ " -> " ++ show err
Right validity ->
putStrLn $ show encodedAddress ++ " -> " ++ if validity then "Valid" else "Invalid"
-- Run some validity check tests.
main :: IO ()
main = do
validate "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" -- VALID
validate "1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9" -- VALID
validate "1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X" -- checksum changed, original data.
validate "1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" -- data changed, original checksum.
validate "1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" -- invalid chars
validate "1ANa55215ZQXAZUgFiqJ2i7Z2DPU2J6hW62i" -- too long
validate "i55j" -- too short