I'm trying to pass a random string (which happens to be a number) "4176730.5" to SHA in Haskell to get a larger random string like "2d711642b726b04401627ca9fbac32f5c8530fb1903cc4db02258717921a4881".
I have this code to generate a random number and cast it to a string
num <- randomIO :: IO Float
let x = C.pack (show (num*10000000))
print x
but when I pass it to SHA with
let a = sha256 x
I get the error
Couldn't match expected type ‘Data.ByteString.Lazy.Internal.ByteString’
with actual type ‘C.ByteString’
I've tried casting my number to C.ByteString, but I think there are two types of Bytestring, according to the Haskell compiler.
The full code is:
import Data.Digest.Pure.SHA
import System.Random
import qualified Data.ByteString.Char8 as C
main :: IO ()
main = do
num <- randomIO :: IO Float
let x = C.pack (show (num*10000000))
print x
let a = sha256 x
b = hmacSha256 "key" "some test message"
mapM_ print [showDigest a, showDigest b]
Seeing as how there are apparently two types of Bytestring, and I'm casting to the wrong one, how do I cast my random string correctly?
Further to @Cubic's answer below if I replace import qualified Data.ByteString.Char8 as C with
import qualified Data.ByteString.Lazy as C
I just get these errors
Couldn't match type ‘Char’ with ‘GHC.Word.Word8’
Expected type: [GHC.Word.Word8]
Actual type: String
and
Couldn't match expected type ‘C.ByteString’
with actual type ‘[Char]’
The issue is that a ByteString
is a sequence of bytes, while a String
is a sequence of chars. There are many ways to turn chars into bytes, so you need to specify which encoding you want. Most likely, you want an ASCII or UTF8 encoding. If so, you can use this solution below, which converts strings into "UTF8 bytes" as needed.
import Data.Digest.Pure.SHA
import System.Random
import qualified Data.ByteString.Lazy as C
import qualified Data.ByteString.Lazy.UTF8 as U
main :: IO ()
main = do
num <- randomIO :: IO Float
let x = U.fromString (show (num*10000000))
print x
let a = sha256 x
b = hmacSha256 (U.fromString "key") (U.fromString "some test message")
mapM_ print [showDigest a, showDigest b]