packages feed

candid 0.3.1 → 0.3.2

raw patch · 4 files changed

+23/−14 lines, 4 files

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for haskell-candid +## 0.3.2 -- 2022-10-07++* Candid hash reversal: Also try upper case+ ## 0.3.1 -- 2022-01-10  * GHC-9.0 compatibility
candid.cabal view
@@ -1,6 +1,6 @@ cabal-version:      >=1.10 name:               candid-version:            0.3.1+version:            0.3.2 license:            Apache license-file:       LICENSE maintainer:         mail@joachim-breitner.de
src/Codec/Candid/Hash.hs view
@@ -30,18 +30,23 @@ invertHash w32 = listToMaybe guesses   where     x = fromIntegral w32 :: Word64+     chars = ['a'..'z'] ++ ['_']     ords = 0 : map (fromIntegral . ord) chars+    init_chars = chars ++ [ 'A'..'Z' ]+    init_ords = 0 : map (fromIntegral . ord) init_chars+     non_mod x = x - (x `mod` 2^(32::Int))     guesses =         [ T.pack $ reverse guess-        | c8 <- ords, c7 <- ords, c6 <- ords, c5 <- ords+        | c8 <- init_ords, c7 <- ords, c6 <- ords, c5 <- ords         -- It seems that 8 characters are enough to invert anything         -- (based on quickchecking)         -- Set up so that short guesses come first         , let high_chars = c5 * 223^(4::Int) + c6 * 223^(5::Int) + c7 * 223^(6::Int) + c8 * 223^(7::Int)         , let guess = simple $ x + non_mod high_chars-        , all (`elem` chars) guess+        , all (`elem` init_chars) (take 1 guess)+        , all (`elem` chars) (drop 1 guess)         ]      -- inverts the Hash if the hash was created without modulos@@ -52,8 +57,10 @@       where (a, b) = x `divMod` 223  -- Word list obtained from https://github.com/dwyl/english-words-ws :: T.Text-ws = $(embedStringFile "words.txt")+wordFile :: T.Text+wordFile = $(embedStringFile "words.txt")  m :: M.IntMap T.Text-m = M.fromList [ (fromIntegral (candidHash w), w) | w <- T.lines ws]+m = M.fromList [ (fromIntegral (candidHash w), w) | w <- word_list ]+  where+    word_list = T.lines wordFile ++ map T.toTitle (T.lines wordFile)
test/test.hs view
@@ -322,8 +322,8 @@     in     [ t True "(true)"     , t (SimpleRecord False 42) "(record {bar = (42 : nat8); foo = false})"-    , t (JustRight (Just (3 :: Natural))) "(variant {gp_jocd = opt 3})"-    , t (JustRight (3 :: Word8)) "(variant {gp_jocd = (3 : nat8)})"+    , t (JustRight (Just (3 :: Natural))) "(variant {Right = opt 3})"+    , t (JustRight (3 :: Word8)) "(variant {Right = (3 : nat8)})"     , t () "()"     , t (Unary ()) "(null)"     , t (Unary (True, False)) "(record {true; false})"@@ -409,13 +409,11 @@       let f' = unescapeFieldName (escapeFieldName f) in       f' == f   , testGroup "candid hash inversion"-    [ QC.testProperty "small names invert" $-        QC.forAll (QC.choose (0,4)) $ \len ->-        QC.forAll (T.pack <$> QC.vectorOf len (QC.elements ('_':['a'..'z']))) $ \s ->-        candidHash s >= 32 QC.==>-        invertHash (candidHash s) QC.=== Just s-    , QC.testProperty "long dictionary name" $+    [ QC.testProperty "long dictionary name" $         let s = "precriticized" in+        invertHash (candidHash s) QC.=== Just s+    , QC.testProperty "long capitalized dictionary name" $+        let s = "Precriticized" in         invertHash (candidHash s) QC.=== Just s     , QC.testProperty "all hashes find something" $         QC.forAll QC.arbitraryBoundedIntegral $ \w ->