From b5df42236969b38bbddcc47cb5cbfdc94a7d3393 Mon Sep 17 00:00:00 2001 From: joe Date: Fri, 13 Oct 2017 15:23:17 -0400 Subject: Switched toxid format from hexadecimal to base64. --- src/Network/Tox/NodeId.hs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/Network/Tox/NodeId.hs b/src/Network/Tox/NodeId.hs index d0c57416..bba56e27 100644 --- a/src/Network/Tox/NodeId.hs +++ b/src/Network/Tox/NodeId.hs @@ -40,6 +40,7 @@ import qualified Data.ByteArray as BA import qualified Data.ByteString as B ;import Data.ByteString (ByteString) import qualified Data.ByteString.Base16 as Base16 +import qualified Data.ByteString.Base64 as Base64 import qualified Data.ByteString.Char8 as C8 import Data.Char import Data.Data @@ -122,15 +123,23 @@ instance Ord NodeId where zeroID :: NodeId zeroID = NodeId $ replicate 4 0 -- throwCryptoError $ publicKey $ B.replicate 32 0 +-- | Convert to and from a Base64 variant that uses .- instead of +/. +nmtoken64 :: Bool -> Char -> Char +nmtoken64 False '.' = '+' +nmtoken64 False '-' = '/' +nmtoken64 True '+' = '.' +nmtoken64 True '/' = '-' +nmtoken64 _ c = c + instance Read NodeId where readsPrec _ str - | (bs, xs) <- Base16.decode $ C8.pack str + | Right bs <- fmap (BA.drop 1) $ Base64.decode $ C8.pack $ 'A':map (nmtoken64 False) (take 43 str) , CryptoPassed pub <- publicKey bs -- B.length bs == 32 - = [ (key2id pub, drop 64 str) ] + = [ (key2id pub, drop 43 str) ] | otherwise = [] instance Show NodeId where - show nid = C8.unpack $ Base16.encode $ BA.convert $ id2key nid + show nid = map (nmtoken64 True) $ C8.unpack $ BA.drop 1 $ Base64.encode $ BA.cons 0 $ BA.convert $ id2key nid instance S.Serialize NodeId where get = key2id <$> getPublicKey @@ -241,18 +250,25 @@ instance S.Serialize NodeInfo where hexdigit :: Char -> Bool hexdigit c = ('0' <= c && c <= '9') || ( 'a' <= c && c <= 'f') || ( 'A' <= c && c <= 'F') +b64digit :: Char -> Bool +b64digit '.' = True +b64digit '+' = True +b64digit '-' = True +b64digit '/' = True +b64digit c = ('0' <= c && c <= '9') || ( 'a' <= c && c <= 'z') || ( 'A' <= c && c <= 'Z') + instance Read NodeInfo where readsPrec i = RP.readP_to_S $ do RP.skipSpaces - let n = 64 -- characters in node id. + let n = 43 -- characters in node id. parseAddr = RP.between (RP.char '(') (RP.char ')') (RP.munch (/=')')) RP.+++ RP.munch (not . isSpace) - nodeidAt = do hexhash <- sequence $ replicate n (RP.satisfy hexdigit) + nodeidAt = do hexhash <- sequence $ replicate n (RP.satisfy b64digit) RP.char '@' RP.+++ RP.satisfy isSpace addrstr <- parseAddr - nid <- case Base16.decode $ C8.pack hexhash of - (bs,_) | B.length bs==32 -> return (bs2id bs) - _ -> fail "Bad node id." + nid <- case Base64.decode $ C8.pack $ 'A' : map (nmtoken64 False) hexhash of + Right bs | B.length bs - 1==32 -> return (bs2id $ BA.drop 1 bs) + _ -> fail "Bad node id." return (nid,addrstr) (nid,addrstr) <- ( nodeidAt RP.+++ ( (zeroID,) <$> parseAddr) ) let raddr = do -- cgit v1.2.3