<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
小弟最近在做網路程式設計的時候,遇到了一些byte資料需要儲存,但是不是常見的str字元對應的byte,類似於b'x00xffxfex01'這樣的資料,查詢資料後發現這種東西是16進位制編碼的byte格式,可以直接轉成str沒有問題,但是再轉回bytes就會出現莫名其妙的雙斜槓,很是頭疼。
a = b'x00xefxa2xa0xb3x8bx9dx1exf8x98x19x39xd9x9dxfdABCDabcd' b = str(a) print(b) >>> b'x00xefxa2xa0xb3x8bx9dx1exf8x98x199xd9x9dxfdABCDabcd' print(bytes(b,'utf8')) >>> b"b'\x00\xef\xa2\xa0\xb3\x8b\x9d\x1e\xf8\x98\x199\xd9\x9d\xfdABCDabcd'"
嘗試寫入檔案,再讀取也是如此,因為寫進去的形式就是str字元
# 寫入data.txt a = b'x00xefxa2xa0xb3x8bx9dx1exf8x98x19x39xd9x9dxfdABCDabcd' with open('data.txt','w') as p: p.write(str(a)) # 讀取data.txt with open('data.txt','r') as p: line = p.readline() print(line, type(line) == str) >>> b'x00xefxa2xa0xb3x8bx9dx1exf8x98x199xd9x9dxfdABCDabcd\' True print(bytes(line,'utf8')) >>> b"b'\x00\xef\xa2\xa0\xb3\x8b\x9d\x1e\xf8\x98\x199\xd9\x9d\xfdABCDabcd\\'"
觀察了一下ASCII碼,發現主要還是因為x字元被理解成了一個斜槓加x的形式,然後被儲存為str形式,相當於變成了兩個位元組。
這樣解碼的時候分開解了,但是xnn這種形式是應該看作ASCII碼的,於是我寫了個跳脫的邏輯進行讀取:
def readbytetxt(filename): dic = { '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 'f': 15, } with open(filename,'r') as p: line = p.readline() while line: if line[-1] == 'n': line = line[:-1] i = 2 L = b'' while i+1 < len(line): if line[i:i+2] == '\x' and (line[i+2] in dic.keys()) and (line[i+3] in dic.keys()): L += bytes([dic[line[i+2]]*16+dic[line[i+3]]]) i += 4 else: L += bytes(line[i],'utf8') i += 1 return L line = p.readline() print(readbytetxt('data.txt')) >>> b'x00xefxa2xa0xb3x8bx9dx1exf8x98x19x39xd9x9dxfdABCDabcd'
問題解決了!基本就是寫了個遍歷,然後遇到x就把16進位制轉成十進位制的int,然後解碼成bytes,這樣常見的十六進位制格式基本都能呼叫了。
後來發現除了x還有其他的跳脫字元,比如\,n,如果不新增轉變邏輯的話,依然會出現不識別的問題,於是重寫了一下函數,支援了常見的大部分跳脫字元,並且寫成了生成器輸出。
def readbytetxt2(filename): dic = { '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 'f': 15, } dic2 = { 'a': 'a', 'b': 'b', 'f': 'f', 'n': 'n', 'r': 'r', 'v': 'v', ''': ''', '"': '', '\': '\', } with open(filename,'r') as p: line = p.readline() while line: if line[-1] == 'n': line = line[:-1] i = 2 L = b'' while i+1 < len(line): if line[i:i+2] == '\x' and (line[i+2] in dic.keys()) and (line[i+3] in dic.keys()): L += bytes([dic[line[i+2]]*16+dic[line[i+3]]]) i += 4 elif line[i] == '\' and line[i+1] in dic2.keys(): L += bytes(dic2[line[i+1]],'utf8') i += 2 elif line[i:i+4] == '\000': L += bytes(' 00','utf8') i += 2 else: L += bytes(line[i],'utf8') i += 1 yield L line = p.readline() a = b'x00xefxa2xa0xb3x8bx9dx1exf8x98x19x39xd9x9dxfdthe first linenrabt\f'"vbn 00' b = b'xa0xdfxa2xa0xb3x8bx9dx1exf8x98x19x39xd9x9dxfdthe second linenn' c = b'xe0xafxa2xa0xb3x8bx9dx1exf8x98x19x39xd9x9dxfdthe third line\' with open('data.txt','w') as p: p.write(str(a)+'n') p.write(str(b)+'n') p.write(str(c)) line = readbytetxt2('data.txt') print([a for a in line]) >>> [b'x00xefxa2xa0xb3x8bx9dx1exf8x98x199xd9x9dxfdthe first linenrx07x08\t\x0c'"x0bx08nx00', b'xa0xdfxa2xa0xb3x8bx9dx1exf8x98x199xd9x9dxfdthe second linenn', b'xe0xafxa2xa0xb3x8bx9dx1exf8x98x199xd9x9dxfdthe third line\']
基本上至此為止,大部分編碼形式都可以搞定了。
但是。。。其實還有一個更簡單的方式!因為其實萬惡之源就是str字元格式裡面有很多跳脫的地方不清不楚的,我想要的是byte存進檔案,再以byte讀出來,而byte格式本來就是16進位制的數位,說到底其實只要能存數位就可以了!所以寫了個更簡單的方法,直接轉成數位存數位列表就好!
L = [] a = b'x00xefxa2xa0xb3x8bx9dx1exf8x98x19x39xd9x9dxfdthe first linenrabt\f'"vbn 00' print(a) for each in a: L.append(int(each)) with open('data.txt','w') as p: p.write(str(L)) print(L) >>> [0, 239, 162, 160, 179, 139, 157, 30, 248, 152, 25, 57, 217, 157, 253, 116, 104, 101, 32, 102, 105, 114, 115, 116, 32, 108, 105, 110, 101, 10, 13, 7, 8, 9, 92, 12, 39, 34, 11, 8, 10, 0] with open('data.txt','r') as p: line = p.readline() print(b''.join([bytes([int(i)]) for i in line[1:-1].split(',')])) >>> b'x00xefxa2xa0xb3x8bx9dx1exf8x98x199xd9x9dxfdthe first linenrx07x08t\x0c'"x0bx08nx00'
存進去的是數位列表,然後用split的方式讀出來就可以了,這樣也不會有各種跳脫搞不清的地方,數位是什麼就讀什麼byte出來就可以了。
十進位制整數轉十六進位制整數用hex();十六進位制整數轉十進位制整數用int()
類似地,十進位制整數轉二進位制整數用bin();十進位制整數轉八進位制整數用oct()
描述:hex() 函數用於將10進位制整數轉換成16進位制,以字串形式表示。
語法:
hex(x)
引數說明:x – 10進位制整數
返回值:返回16進位制數,以字串形式表示。
描述:int() 函數用於將一個字串或數位轉換為整型。
語法:
class int(x, base=10)
引數說明:x – 字串或數位。base – 進位制數,預設十進位制。
返回值:返回整型資料。
對於十六進位制整數,在進行運算前先轉換成十進位制整數,再對其進行運算,之後將運算結果轉換回十六進位制數。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45