每次電腦重裝都得煩心,要把龐大的IDE重新配置一次,正准備安裝Visual Stdio 2010,上網找鏡像的時候發現,Visual Stdio 2013推出了Community版,不僅沒有lite掉,而且還全免費!這里Post個官方的鏡像下載地址先(Visual Stdio Community 2013),破解版就別用啦,反正不是商用,社區版足矣。
既然安裝好了最新版的VS,自然要來弄點東西解解饞,最近一直在做RFID的項目,正需要一個Windows版的dump轉txt工具,雖說有Mifare Classic Tools提供的Bash腳本,還有Python版,但Windows上使用始終是不方便,所以決定用VB.Net來做一個。不得不說,最新的.Net的確讓人有點受不了,代碼臃腫,但的確語言是越來越高級了,跟F#一樣,開始接近人類自然語言了,效率嘛相對來說比之前也好了一些,但是畢竟是要用虛擬機運行的,要求就不要太高了。
不說廢話,貼出關鍵代碼。
1 'Project Name:Dump2Text 2 'Version:1.1 3 'IDE:Visual Stdio 2013-Visual Basic.Net 4 'Designed by Sirius Web-bobylive 5 'http://bobylive.com 6 'Email:i#boby.im (Replace # into @) 7 'Date:2015-02-16 8 9 Dim DumpData As String, ReadData As Byte, ReadCircle As Byte, ReadChangeLine As Byte, TextName As String, TextPath As String, FilePath As String = TextBoxFilePath.Text '定義變量 10 If FilePath <> "" Then '保證文件目錄不為空,否則下面處理將會出錯,其實這里應該還增加一個檢測文件是否存在的,1.2版本的時候再奉上 11 TextBoxFilePath.Text = FilePath 12 Dim SetDump As New IO.FileStream(FilePath, IO.FileMode.Open) '打開文件句柄,使用FileStream 13 Dim ReaDump As New IO.BinaryReader(SetDump) '因為是binary文件,所以使用BinaryReader,byte讀出 14 TextName = My.Computer.FileSystem.GetName(FilePath) '獲取Dump的文件名 15 TextPath = My.Computer.FileSystem.GetParentPath(FilePath) '獲取文件路徑 16 ReaDump.BaseStream.Position = 0 '指針設置為0,VB引入了指針還是很方便的 17 DumpData = "" 18 Select Case ReaDump.BaseStream.Length '針對1k和4k的Dump進行處理 19 Case 1024 20 Do 21 ReadData = ReaDump.ReadByte 22 ReadCircle += 1 23 DumpData &= Hex(ReadData).PadLeft(2, "0") '修正讀出字節格式 24 If ReadCircle = 16 Then '分段 25 DumpData &= vbCrLf 26 ReadCircle = 0 27 ReadChangeLine += 1 28 End If 29 If ReadChangeLine = 4 Then '分扇區 30 DumpData &= vbCrLf 31 ReadChangeLine = 0 32 End If 33 Loop While ReaDump.BaseStream.Position < ReaDump.BaseStream.Length '到文件末端的時候結束讀取,這種方法一大亮點 34 SetDump.Close() '記得關閉文件句柄 35 ReaDump.Close() 36 My.Computer.FileSystem.WriteAllText(TextPath & "\" & TextName & ".txt", DumpData, False, System.Text.Encoding.Default) '寫入txt 37 MessageBox.Show("Cotvert Successful!", "Congratulation!", MessageBoxButtons.OK) 38 Case 4096 39 Do While ReaDump.BaseStream.Position < 1024 '忽略4k文件后面空白部分 40 ReadData = ReaDump.ReadByte 41 ReadCircle += 1 42 DumpData &= Hex(ReadData).PadLeft(2, "0") 43 If ReadCircle = 16 Then 44 DumpData &= vbCrLf 45 ReadCircle = 0 46 ReadChangeLine += 1 47 End If 48 If ReadChangeLine = 4 Then 49 DumpData &= vbCrLf 50 ReadChangeLine = 0 51 End If 52 Loop 53 SetDump.Close() 54 ReaDump.Close() 55 My.Computer.FileSystem.WriteAllText(TextPath & "\" & TextName & ".txt", DumpData, False, System.Text.Encoding.Default) 56 MessageBox.Show("Cotvert Successful!", "Congratulation!", MessageBoxButtons.OK) 57 End Select 58 Else 59 MessageBox.Show("Please Select A Correct File!", "Error", MessageBoxButtons.OK) 60 End If
這里給大家再講解一下幾個難點,其他的請看代碼注釋。
1、讀取出來的字節必須用Hex()函數進行轉換,否則將以十進制顯示,而且對讀出來的字節必須調用PadLeft過程進行format,比如如果讀取出來02,系統就會將其處理為2,PadLeft可以將其重新修正為02。
2、我使用了ReadCircle記錄讀出的字節,用ReadChangeLine記錄段數,大家也都知道,S50卡都是每段16個字節,4段一個扇區,我用vbCrLf為他們換行,還原了Dump原有的格式。
3、為什么我要用Select Case進行兩個操作呢。因為Dump文件有兩種標准,一種是1k,一種是4k,4k在1024字節之后全空白,沒必要進行轉換,所以在文件流指針到達1024時候就退出循環。
4、判斷EOF的時候不要用peekchar()!.Net中peekchar()可以預讀下一位但保持指針地址不變,返回值為-1時表示到達文件末端,但是如果編碼格式存在不同,就會出現異常,這是.Net的一個Bug,所以我們用BaseStream.Length獲取整個文件的長度,然后跟指針位置BaseStream.Position進行比較,文件指針位置跟文件長度相等的時候就退出循環。
程序稍微做了一下界面。如圖
代碼其實還是有缺陷的,但是現在還沒時間去完善,等過兩天在Post個1.2版本上來。這里先放個1.1的給大家嘗嘗鮮,點擊文本框可以選擇文件,然后點按鈕就會開始轉換,在Dump文件同個目錄下生成同名txt。注意要裝.Net框架哦!
Download Dump2Text (Version 1.1)