練習 26: hexdump
hexdump
原文: Exercise 26: hexdump 譯者: 飛龍 協定: CC BY-NC-SA 4.0 自豪地采用 谷歌翻譯
你已經用
xargs
完成了熱身,現在正在代碼/審計的循環中。你現在将嘗試以“測試優先”方式完成下一個挑戰。這就是,你編寫測試,它描述你的預期行為,然後實作該行為,直到通過測試。你将要複制
hexdump
工具,并嘗試将你的版本的輸出與真實版本比對。這是“測試優先”開發真正有幫助的地方,因為它自動化了模仿另一個軟體的流程。
當你需要編寫一個糟糕的軟體的替代品時,這種技術非常有用。軟體中的一個常見工作是處理一個項目,它的目的是使用更新的實作替換舊系統。一個例子是用一個新的、熱門的 Django 系統來替換舊的 COBOL 銀行系統。動機通常是,通過使用比舊系統更容易使用的東西,來使其更容易維護和擴充。如果你可以編寫一組自動測試來驗證舊系統的行為,然後将該測試套件用于新系統,那麼你可以通過一種方法,來确認你的替換品幾乎正常。相信我,這些替代工作幾乎是不可能的,通常不會成功,但自動測試是有幫助的。
這個練習中,你會向你的流程添加下面這些:
- 在你需要實作的場景中,編寫一個測試用例,運作原始的
。讓我們假設hexdump
選項。你将需要使用-C
啟動它,或者簡單地提前運作它,并将結果儲存到加載的檔案。subprocess
- 通過測試你的
版本,然後比較結果,編寫使測試工作的代碼。如果他們不等價,那麼你就做錯了。hexdump
- 然後審計測試代碼和你的代碼。
我選擇了
hexdump
,因為難度在于,複制其奇怪的輸出格式來檢視二進制資料。它的工作方式不是特别複雜。它隻是比對你需要的正确輸出。這有助于你練習“測試優先”的測試。
注
當我說“先寫一個測試”時,我的意思并不是一個龐大的
檔案,它具有所有的函數和大量的虛構代碼。我的意思是我以前教過的東西。編寫一個小型測試用例 - 也許隻是一個測試函數的1/10,然後編寫代碼使其正常工作,然後在兩者之間來回跳動。你越了解代碼,你就可以寫出越多的測試用例,但不要寫一堆測試代碼,并沒有東西來運作它。而是要逐漸編寫。
test.py
挑戰練習
當你想要檢視不是可見文本的檔案内容時,
hexdump
指令很有用。它以各種有用的格式顯示檔案中的位元組,包括十六進制,八進制,并且後面帶有 ASCII 輸出。實作自己的
hexdump
的難度不是讀取資料,甚至不是将其轉換為不同的格式。你可以使用 Python 中的
hex
,
oct
int
和
ord
函數輕松地執行此操作。原始的格式化字元串運算符也很有用,因為它為固定精度的八進制和十六進制格式化提供了選項。
真正的困難在于為每個不同的選項正确格式化輸出,以便它能夠正确流動并适合螢幕。以下是Python .pyc檔案的hexdump -C輸出的前幾行:
真正的困難在于為每個不同的選項正确格式化輸出,以便它能夠正确列印并适合螢幕。以下是
Python .pyc
檔案的
hexdump -C
輸出的前幾行:
00000000 03 f3 0d 0a f0 b5 69 57 63 00 00 00 00 00 00 00 |......iWc.......|
00000010 00 03 00 00 00 40 00 00 00 73 3a 00 00 00 64 00 |[email protected]:...d.|
00000020 00 64 01 00 6c 00 00 6d 01 00 5a 01 00 01 64 00 |.d..l..m..Z...d.|
00000030 00 64 02 00 6c 02 00 6d 03 00 5a 03 00 01 64 03 |.d..l..m..Z...d.|
00000040 00 65 01 00 66 01 00 64 04 00 84 00 00 83 00 00 |.e..f..d........|
這個“規範”格式化的手冊頁說:
以十六進制顯示輸入偏移量。是以 10 不是十進制中的 10,它是十六進制。你知道十六進制嗎?
十六個空格分隔的,兩列十六進制位元組。這是轉換為十六進制的每個位元組。多少列代表一個位元組?
然後以
%_p
格式顯示相同的十六個位元組,看起來像 Python 格式化占位符,但它專用于 hexdump。你需要閱讀更多手冊頁,來了解其含義。
之後
hexdump
也可以從
stdin
輸入接收輸入,這意味着你可以将東西使用管道連接配接到它:
echo "Hello There" | hexdump -C
這會在我的 macOS 上産生如下輸出:
00000000 48 65 6c 6c 6f 20 54 68 65 72 65 0a |Hello There.|
0000000c
請注意,最後一行有一個字元
c
?猜猜看這是什麼。
這就是格式化和輸出,它比較困難,你的任務是盡可能複制它,這就是為什麼這個練習的開頭讓你以“測試優先”的方式工作。建立測試,将你的資料扔給
hexdump
将會更容易,并将其與真正的
hexdump
進行比較,直到它開始工作。
研究性學習
研究
od
指令,看看你的
hexdump
代碼是否可以複用于
od
的實作。如果可以的話,可以制作一個他們都使用的庫。
深入學習
有人主張隻做“測試優先”的開發,但我相信沒有永遠适用的技術。當我從使用者的角度測試軟體的互動時,我更喜歡寫測試。我将編寫測試,它描述了使用者與軟體的互動,然後實作軟體。這是你所做的事情,因為你正在測試,使用者如何從你的
hexdump
指令行調用中看到輸出。
對于其他類型的程式設計任務,決定首先寫測試還是編寫代碼是荒謬的,隻會扼殺你解決問題的能力。自動化測試是簡單的工具,你是一個聰明的人,有權力嘗試使用工具,但你認為他們将在每種情況下都能最好地工作。任何告訴你差別的人可能是一個無理取鬧的人,實際上并不擅長程式設計。