[英]Manipulating hexadecimal data in Haskell
我有一個CSV文件,其中記錄了所有數據,我想在Haskell中進行處理。 CSV文件中的數據為十六進制格式。 當我將其讀入Haskell時,我會看到諸如“ 0xFF5FFFC8EC5FFEDF”之類的字符串,它代表8個字節的數據。
為了處理數據,我想將字符串轉換為數據類型,這將允許我進行位旋轉(按位AND,OR和XOR)。 然后,當我完成后,我想將最終結果轉換回十六進制字符串,以便將其寫入文件。
在Haskell這樣做容易嗎? 我應該看哪個模塊?
您可以使用read
解析int或float。 它位於Prelude中,因此您可以使用它而無需任何其他模塊。
嘗試:
a = "0xFF5FFFC8EC5FFEDF"
b = read a::Double
(它給出b = 1.8401707840883393e19)
另外,對於解析CSV,您也可以自己編寫函數來執行。 我一周前才寫了一個簡單的CSV解析器。
module CSVUtils
( parseCSV, showCSV
, readCSV , writeCSV
, colFields
, Separator, Document
, CSV , Entry
, Field
)
where
import Data.Char
import Data.List
{-
A simple utility for working with CSV (comma-separated value) files. These
are simple textual files where fields are delimited with a character (usually a comma
or a semicolon). It is required that the CSV document is well-formed, i.e., that
it contains an equal number of fields per row.
-}
type Separator = String
type Document = String
type CSV = [Entry]
type Entry = [Field]
type Field = String
doc = "John;Doe;15\nTom;Sawyer;12\nAnnie;Blake;20"
brokenDoc = "One;Two\nThree;Four;Five"
{-
(a) Takes a separator and a string representing a CSV document and returns a
CSV representation of the document.
-}
-- !! In the homework text is said Separator is going to be Char and now the type is String
-- !! so I'm just going to take head
parseCSV :: Separator -> Document -> CSV
parseCSV sep doc
| (head sep) `notElem` doc = error $ "The character '"++sep++"' does not occur in the text"
| 1 /= length ( nub ( map length (lines doc))) = error $ "The CSV file is not well-formed"
| otherwise = [splitOn sep wrd | wrd <- lines doc ]
{-
(b) Takes a separator and a CSV representation of
a document and creates a CSV string from it.
-}
showCSV :: Separator -> CSV -> Document
showCSV sep = init . unlines . map (intercalate sep)
{-
(c) Takes a CSV document and a field number
and returns a list of fields in that column.
-}
colFields :: Int -> CSV -> [Field]
colFields n csv = [ if length field > n
then field !! n
else error $ "There is no column "++(show n)++" in the CSV document"
| field <- csv]
{-
(d) Takes a file path and a separator and returns the CSV representation of the file.
-}
readCSV :: Separator -> FilePath -> IO CSV
readCSV sep path = do
file <- readFile path
return $ parseCSV sep file
{-
(e) Takes a separator, a file path, and a CSV document and writes the document into a file.
The return type of writeCSV is a special case of IO { we need to wrap an impure
action, but do not actually have to return anything when writing. Thus, we
introduce (), or the unit type, which holds no information (consider it a 0-
tuple).
-}
writeCSV :: Separator -> FilePath -> CSV -> IO ()
writeCSV sep path csv = writeFile path (showCSV sep csv)
我將假設您的二進制數據可以具有任意長度。 例如,如果您的二進制數據適合Int64
,則事情可以簡化。
我將推薦以下庫和模塊:
有關如何對ByteStrings執行按位運算的示例,請查看Haskell學校的本教程結尾:
https://www.fpcomplete.com/school/to-infinity-and-beyond/pick-of-the-week/bytestring-bits-and-pieces
有關如何使用cassava
的examples
,請查看源存儲庫的examples
目錄:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.