diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/candid.cabal b/candid.cabal
--- a/candid.cabal
+++ b/candid.cabal
@@ -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
diff --git a/src/Codec/Candid/Hash.hs b/src/Codec/Candid/Hash.hs
--- a/src/Codec/Candid/Hash.hs
+++ b/src/Codec/Candid/Hash.hs
@@ -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)
diff --git a/test/test.hs b/test/test.hs
--- a/test/test.hs
+++ b/test/test.hs
@@ -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 ->
