亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Python > 正文

Python實現Linux命令xxd -i功能

2020-01-04 17:39:04
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了Python實現Linux命令xxd -i功能的相關資料,需要的朋友可以參考下
 

一. Linux xxd -i功能

Linux系統xxd命令使用二進制或十六進制格式顯示文件內容。若未指定outfile參數,則將結果顯示在終端屏幕上;否則輸出到outfile中。詳細的用法可參考linux命令xxd。

本文主要關注xxd命令-i選項。使用該選項可輸出以inputfile為名的C語言數組定義。例如,執行echo 12345 > test和xxd -i test命令后,輸出為:

unsigned char test[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x0a};unsigned int test_len = 6;

可見,數組名即輸入文件名(若有后綴名則點號替換為下劃線)。注意,0x0a表示換行符LF,即'/n'。

二. xxd -i常見用途

當設備沒有文件系統或不支持動態內存管理時,有時會將二進制文件(如引導程序和固件)內容存儲在C代碼靜態數組內。此時,借助xxd命令就可自動生成版本數組。舉例如下:

1) 使用Linux命令xdd將二進制文件VdslBooter.bin轉換為16進制文件DslBooter.txt:

xxd -i < VdslBooter.bin > DslBooter.txt

其中,'-i'選項表示輸出為C包含文件的風格(數組方式)。重定向符號'<'將VdslBooter.bin文件內容重定向到標準輸入,該處理可剔除數組聲明和長度變量定義,使輸出僅包含16進制數值。

2) 在C代碼源文件內定義相應的靜態數組:

static const uint8 bootImageArray[] = {#include " ../../DslBooter.txt"};TargetImage bootImage = {(uint8 *) bootImageArray,sizeof(bootImageArray) / sizeof(bootImageArray[0])};

編譯源碼時,DslBooter.txt文件的內容會自動展開到上述數組內。通過巧用#include預處理指令,可免去手工拷貝數組內容的麻煩。

三. 類xxd -i功能的Python實現

本節將使用Python2.7語言實現類似xxd -i的功能。

因為作者處于學習階段,代碼中存在許多寫法不同但功能相同或相近的地方,旨在提供不同的語法參考,敬請諒解。

首先,請看一段短小卻完整的程序(保存為xddi.py):

#!/usr/bin/python#coding=utf-8#判斷是否C語言關鍵字CKeywords = ("auto", "break", "case", "char", "const", "continue", "default","do","double","else","enum","extern","float","for","goto","if","int","long","register","return","short","signed","static","sizeof","struct","switch","typedef","union","unsigned","void","volatile","while", "_Bool") #_Bool為C99新關鍵字def IsCKeywords(name):for x in CKeywords:if cmp(x, name) == 0:return Truereturn Falseif __name__ == '__main__':print IsCKeywords('const')#Xxdi()

這段代碼判斷給定的字符串是否為C語言關鍵字。在Windows系統cmd命令提示符下輸入E:/PyTest>python xxdi.py,執行結果為True。

接下來的代碼片段將省略頭部的腳本和編碼聲明,以及尾部的'main'段。

生成C數組前,應確保數組名合法。C語言標識符只能由字母、數字和下劃線組成,且不能以數字開頭。此外,關鍵字不能用作標識符。所有,需要對非法字符做處理,其規則參見代碼注釋:

import redef GenerateCArrayName(inFile):#字母數字下劃線以外的字符均轉為下劃線#'int $=5;'的定義在Gcc 4.1.2可編譯通過,但此處仍視為非法標識符inFile = re.sub('[^0-9a-zA-Z/_]', '_', inFile) #'_'改為''可剔除非法字符#數字開頭加雙下劃線if inFile[0].isdigit() == True:inFile = '__' + inFile#若輸入文件名為C語言關鍵字,則將其大寫并加下劃線后綴作為數組名#不能僅僅大寫或加下劃線前,否則易于用戶自定義名沖突if IsCKeywords(inFile) is True:inFile = '%s_' %inFile.upper()return inFile

以print GenerateCArrayName('1a$if1#1_4.txt')執行時,入參字符串將被轉換為__1a_if1_1_4_txt。類似地,_Bool被轉換為_BOOL_。

為了盡可能模擬Linux命令風格,還需提供命令行選項和參數。解析模塊選用optionparser,其用法詳見python命令行解析。類xxd -i功能的命令行實現如下:

#def ParseOption(base, cols, strip, inFile, outFile):def ParseOption(base = 16, cols = 12, strip = False, inFile = '', outFile = None):from optparse import OptionParsercustUsage = '/n xxdi(.py) [options] inFile [outFile]'parser = OptionParser(usage=custUsage)parser.add_option('-b', '--base', dest='base',help='represent values according to BASE(default:16)')parser.add_option('-c', '--column', dest='col',help='COL octets per line(default:12)')parser.add_option('-s', '--strip', action='store_true', dest='strip',help='only output C array elements')(options, args) = parser.parse_args()if options.base is not None:base = int(options.base)if options.col is not None:cols = int(options.col)if options.strip is not None:strip = Trueif len(args) == 0:print 'No argument, at least one(inFile)!/nUsage:%s' %custUsageif len(args) >= 1:inFile = args[0]if len(args) >= 2:outFile = args[1]return ([base, cols, strip], [inFile, outFile])

被注釋掉的def ParseOption(...)原本是以下面的方式調用:

base = 16; cols = 12; strip = False; inFile = ''; outFile = ''([base, cols, strip], [inFile, outFile]) = ParseOption(base,cols, strip, inFile, outFile)

其意圖是同時修改base、cols、strip等參數值。但這種寫法非常別扭,改用缺省參數的函數定義方式,調用時只需要寫ParseOption()即可。若讀者知道更好的寫法,望不吝賜教。

以-h選項調出命令提示,可見非常接近Linux風格:

E:/PyTest>python xxdi.py -hUsage:xxdi(.py) [options] inFile [outFile]Options:-h, --help show this help message and exit-b BASE, --base=BASE represent values according to BASE(default:16)-c COL, --column=COL COL octets per line(default:12)-s, --strip only output C array elements

基于上述練習,接著完成本文的重頭戲:

def Xxdi():#解析命令行選項及參數([base, cols, strip], [inFile, outFile]) = ParseOption()import osif os.path.isfile(inFile) is False:print ''''%s' is not a file!''' %inFilereturnwith open(inFile, 'rb') as file: #必須以'b'模式訪問二進制文件#file = open(inFile, 'rb') #Python2.5以下版本不支持with...as語法#if True:#不用for line in file或readline(s),以免遇'0x0a'換行content = file.read()#將文件內容"打散"為字節數組if base is 16: #Hexadecimalcontent = map(lambda x: hex(ord(x)), content)elif base is 10: #Decimalcontent = map(lambda x: str(ord(x)), content)elif base is 8: #Octalcontent = map(lambda x: oct(ord(x)), content)else:print '[%s]: Invalid base or radix for C language!' %basereturn#構造數組定義頭及長度變量cArrayName = GenerateCArrayName(inFile)if strip is False:cArrayHeader = 'unsigned char %s[] = {' %cArrayNameelse:cArrayHeader = ''cArrayTailer = '};/nunsigned int %s_len = %d;' %(cArrayName, len(content))if strip is True: cArrayTailer = ''#print會在每行輸出后自動換行if outFile is None:print cArrayHeaderfor i in range(0, len(content), cols):line = ', '.join(content[i:i+cols])print ' ' + line + ','print cArrayTailerreturnwith open(outFile, 'w') as file:#file = open(outFile, 'w') #Python2.5以下版本不支持with...as語法#if True:file.write(cArrayHeader + '/n')for i in range(0, len(content), cols):line = reduce(lambda x,y: ', '.join([x,y]), content[i:i+cols])file.write(' %s,/n' %line)file.flush()file.write(cArrayTailer)

Python2.5以下版本不支持with...as語法,而作者調試所用的Linux系統僅裝有Python2.4.3。因此,要在Linux系統中運行xddi.py,只能寫為file = open(...。但這需要處理文件的關閉和異常,詳見理解Python中的with…as…語法。注意,Python2.5中使用with...as語法時需要聲明from __future__ import with_statement。

可通過platform.python_version()獲取Python版本號。例如:

import platform#判斷Python是否為major.minor及以上版本def IsForwardPyVersion(major, minor):#python_version()返回'major.minor.patchlevel',如'2.7.11'ver = platform.python_version().split('.')if int(ver[0]) >= major and int(ver[1]) >= minor:return Truereturn False

經過Windows和Linux系統雙重檢驗后,Xddi()工作基本符合預期。以123456789ABCDEF.txt文件(內容為'123456789ABCDEF')為例,測試結果如下:

E:/PyTest>python xxdi.py -c 5 -b 2 -s 123456789ABCDEF.txt[2]: Invalid base or radix for C language!E:/Pytest>python xxdi.py -c 5 -b 10 -s 123456789ABCDEF.txt49, 50, 51, 52, 53,54, 55, 56, 57, 65,66, 67, 68, 69, 70,E:/PyTest>python xxdi.py -c 5 -b 10 123456789ABCDEF.txtunsigned char __123456789ABCDEF_txt[] = {49, 50, 51, 52, 53,54, 55, 56, 57, 65,66, 67, 68, 69, 70,};unsigned int __123456789ABCDEF_txt_len = 15;E:/PyTest>python xxdi.py -c 5 -b 8 123456789ABCDEF.txtunsigned char __123456789ABCDEF_txt[] = {061, 062, 063, 064, 065,066, 067, 070, 071, 0101,0102, 0103, 0104, 0105, 0106,};unsigned int __123456789ABCDEF_txt_len = 15;E:/PyTest>python xxdi.py 123456789ABCDEF.txtunsigned char __123456789ABCDEF_txt[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43,0x44, 0x45, 0x46,};unsigned int __123456789ABCDEF_txt_len = 15;

再以稍大的二級制文件為例,執行 python xxdi.py VdslBooter.bin booter.c后,booter.c文件內容如下(截取首尾):

unsigned char VdslBooter_bin[] = {0xff, 0x31, 0x0, 0xb, 0xff, 0x3, 0x1f, 0x5a, 0x0, 0x0, 0x0, 0x0,//... ... ... ...0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,};unsigned int VdslBooter_bin_len = 53588;

綜上可見,作者實現的xxdi模塊與Linux xxd -i功能非常接近,且各有優劣。xxdi優點在于對數組名合法性校驗更充分(關鍵字檢查),數組內容表現形式更豐富(8進制和10進制);缺點在于不支持重定向,且數值寬度不固定(如0xb和0xff)。當然,這些缺點并不難消除。例如,用'0x%02x'%val代替hex(val)即可控制輸出位寬。只是,再加完善難免提高代碼復雜度,也許會事倍功半。

以上所述是小編給大家介紹的Python實現Linux命令xxd -i功能,希望對大家以上幫助!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美精品在线视频观看| 亚洲精品v欧美精品v日韩精品| 亚洲另类激情图| 亚洲精品大尺度| 日韩中文有码在线视频| 少妇高潮久久久久久潘金莲| 久久久精品久久久| 欧美中文字幕第一页| 国内免费久久久久久久久久久| 国产精品1234| 亚洲精品丝袜日韩| 亚洲女同精品视频| 国产日韩欧美在线看| 国产九九精品视频| 国产精品揄拍500视频| 国产精品女主播视频| 中文字幕日韩欧美精品在线观看| 日本中文字幕不卡免费| 国内外成人免费激情在线视频| 国产精品十八以下禁看| 久久影视免费观看| 久久成人一区二区| 亚洲欧洲午夜一线一品| 欧美一区在线直播| 伊人av综合网| 亚洲综合日韩在线| 成人免费午夜电影| 一区二区三区动漫| 欧美国产日韩免费| 久热精品视频在线| 国产九九精品视频| 欧洲午夜精品久久久| 8090理伦午夜在线电影| 91久久国产精品| 欧美日韩国产精品| 精品美女久久久久久免费| 午夜精品久久久99热福利| 欧美在线视频免费观看| 久久久天堂国产精品女人| 欧美亚州一区二区三区| 亚洲一区免费网站| 中文字幕精品—区二区| 最近2019免费中文字幕视频三| 国产精品久久久久久久久久东京| 亚洲美女喷白浆| 日韩精品视频在线观看免费| 国产精品极品美女在线观看免费| 久久亚洲一区二区三区四区五区高| 国产精品www网站| 亚洲第一精品久久忘忧草社区| 午夜精品久久久久久久白皮肤| 91精品国产乱码久久久久久久久| 性色av一区二区三区在线观看| 日韩精品免费电影| 国产精品亚洲片夜色在线| 国产精品视频男人的天堂| 欧美激情视频在线免费观看 欧美视频免费一| 欧美日韩在线一区| 日本久久久久亚洲中字幕| 91午夜理伦私人影院| 国产一区二区精品丝袜| 色偷偷av一区二区三区乱| 欧美视频在线观看免费网址| 亚洲片国产一区一级在线观看| 亚洲女人初尝黑人巨大| 日韩电影中文字幕在线观看| 日韩欧美aⅴ综合网站发布| 日韩成人xxxx| 欧美夫妻性视频| 日韩极品精品视频免费观看| 久久大大胆人体| 91精品久久久久久久久久久久久久| xxav国产精品美女主播| 成人久久久久爱| 日韩在线视频线视频免费网站| 久久免费视频这里只有精品| 欧美视频专区一二在线观看| 一个人看的www久久| 精品一区二区亚洲| 热99精品只有里视频精品| 国产精品一区二区久久国产| 亚洲男人av在线| 国产日韩欧美夫妻视频在线观看| 亚洲成人激情在线观看| 欧美日韩高清区| 国内精品久久久久影院优| 国模精品系列视频| 成人写真视频福利网| 国产精品人成电影在线观看| 亚洲免费伊人电影在线观看av| 亚洲天堂网在线观看| 久久久久在线观看| 2019中文字幕免费视频| 国产这里只有精品| 亚洲乱码国产乱码精品精天堂| 亚洲欧美一区二区激情| 日韩亚洲第一页| 亚洲风情亚aⅴ在线发布| 国产精品久久久久免费a∨| 久久天天躁狠狠躁夜夜爽蜜月| 欧美整片在线观看| 日韩成人av网址| 中文字幕一精品亚洲无线一区| 国产精品一区二区三区毛片淫片| 性色av一区二区三区在线观看| 欧美亚洲一区在线| 国产精品久久久久久搜索| 97在线精品视频| 亚洲欧美三级伦理| 欧美极品在线播放| 91av成人在线| 国模吧一区二区| 日韩在线欧美在线国产在线| 亚洲xxxx18| 久久人人爽亚洲精品天堂| 久久久久久噜噜噜久久久精品| 国产精品视频自在线| 人九九综合九九宗合| 最近中文字幕日韩精品| 伊人久久久久久久久久久| 欧美性猛交xxxx免费看| 亚洲国产女人aaa毛片在线| 欧美午夜激情在线| 国产精品视频资源| 精品五月天久久| 日韩av在线高清| 亚洲免费视频观看| 成人免费在线视频网址| 日韩在线激情视频| 精品中文字幕视频| 国产精品免费久久久久久| 色哟哟入口国产精品| 日韩av免费在线看| 国产精品视频一区二区高潮| 在线播放亚洲激情| 九九热这里只有在线精品视| 日韩成人在线免费观看| 欧美最顶级的aⅴ艳星| 亚洲欧洲日产国码av系列天堂| 欧美电影在线观看| 国产一区二区三区网站| 国产精品久久97| 欧美激情区在线播放| 精品视频一区在线视频| 欧美在线性爱视频| 国产精品普通话| 国产精品一区二区在线| 国产精品久久久久久久天堂| 91九色蝌蚪国产| 91高清在线免费观看| 国产精品日韩欧美综合| 国产精品视频网| 欧美精品xxx| 91丨九色丨国产在线| 欧美日韩国产精品一区二区三区四区| 精品国产一区二区三区四区在线观看| 欧美国产第一页| 亚洲精品久久久久中文字幕欢迎你| 国产91色在线免费| 亚洲精品短视频| 亚洲女同性videos| 成人xxxx视频| 成人在线一区二区| 国产成人精品久久久|