天天看點

笨辦法學 Python · 續 練習 26:`hexdump`練習 26:hexdump

練習 26:

hexdump

原文: Exercise 26: hexdump 譯者: 飛龍 協定: CC BY-NC-SA 4.0 自豪地采用 谷歌翻譯

你已經用

xargs

完成了熱身,現在正在代碼/審計的循環中。你現在将嘗試以“測試優先”方式完成下一個挑戰。這就是,你編寫測試,它描述你的預期行為,然後實作該行為,直到通過測試。你将要複制

hexdump

工具,并嘗試将你的版本的輸出與真實版本比對。這是“測試優先”開發真正有幫助的地方,因為它自動化了模仿另一個軟體的流程。

當你需要編寫一個糟糕的軟體的替代品時,這種技術非常有用。軟體中的一個常見工作是處理一個項目,它的目的是使用更新的實作替換舊系統。一個例子是用一個新的、熱門的 Django 系統來替換舊的 COBOL 銀行系統。動機通常是,通過使用比舊系統更容易使用的東西,來使其更容易維護和擴充。如果你可以編寫一組自動測試來驗證舊系統的行為,然後将該測試套件用于新系統,那麼你可以通過一種方法,來确認你的替換品幾乎正常。相信我,這些替代工作幾乎是不可能的,通常不會成功,但自動測試是有幫助的。

這個練習中,你會向你的流程添加下面這些:

  • 在你需要實作的場景中,編寫一個測試用例,運作原始的

    hexdump

    。讓我們假設

    -C

    選項。你将需要使用

    subprocess

    啟動它,或者簡單地提前運作它,并将結果儲存到加載的檔案。
  • 通過測試你的

    hexdump

    版本,然後比較結果,編寫使測試工作的代碼。如果他們不等價,那麼你就做錯了。
  • 然後審計測試代碼和你的代碼。

我選擇了

hexdump

,因為難度在于,複制其奇怪的輸出格式來檢視二進制資料。它的工作方式不是特别複雜。它隻是比對你需要的正确輸出。這有助于你練習“測試優先”的測試。

當我說“先寫一個測試”時,我的意思并不是一個龐大的

test.py

檔案,它具有所有的函數和大量的虛構代碼。我的意思是我以前教過的東西。編寫一個小型測試用例 - 也許隻是一個測試函數的1/10,然後編寫代碼使其正常工作,然後在兩者之間來回跳動。你越了解代碼,你就可以寫出越多的測試用例,但不要寫一堆測試代碼,并沒有東西來運作它。而是要逐漸編寫。

挑戰練習

當你想要檢視不是可見文本的檔案内容時,

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

指令行調用中看到輸出。

對于其他類型的程式設計任務,決定首先寫測試還是編寫代碼是荒謬的,隻會扼殺你解決問題的能力。自動化測試是簡單的工具,你是一個聰明的人,有權力嘗試使用工具,但你認為他們将在每種情況下都能最好地工作。任何告訴你差別的人可能是一個無理取鬧的人,實際上并不擅長程式設計。