python整數、字符串、字節串

python整數、字符串、字節串

一、整數、字符串、字節串之間的相互轉換

1.進制轉換

10進制轉16進制(注意轉換出來的是16進制字符串):

hex(16)  ==>  0x10

16進制轉10進制:

int(STRING,BASE)將字符串STRING轉成十進制int,其中STRING的基是base。該函數的第一個參數是字符串

int('0x10', 16)  ==>  16

類似的還有八進制oct(), 二進制bin()

16進制字符串轉成二進制

hex_str='00fe'
bin(int('1'+hex_str, 16))[3:]  #含有前導0
# 結果 '0000000011111110'
bin(int(hex_str, 16))[2:]   #忽略前導0
# 結果 '11111110'

二進制字符串轉成16進制字符串

bin_str='0b0111000011001100'
hex(int(bin_str,2))
# 結果 '0x70cc'

2.字符to整數

10進制字符串:

int('10')  ==>  10

16進制字符串:

int('10', 16)  ==>  16
# 或者
int('0x10', 16)  ==>  16

3.字節串to整數

使用網絡數據包常用的struct,兼容C語言的數據結構
struct中支持的格式如下表

Format C-Type Python-Type 字節數 備註
x pad byte no value 1
c char string of length 1 1
b signed char integer 1
B unsigned char integer 1
? _Bool bool 1
h short integer 2
H unsigned short integer 2
i int integer 4
I unsigned int integer or long 4
l long integer 4
L unsigned long long 4
q long long long 8 僅支持64bit機器
Q unsigned long long long 8 僅支持64bit機器
f float float 4
d double float 8
s char[] string 1
p char[] string 1(與機器有關) 作爲指針
P void * long 4 作爲指針

對齊方式:放在第一個fmt位置(struct包的使用)

CHARACTER BYTE ORDER SIZE ALIGNMENT
@ native native native
= native standard none
< little-endian standard none
> big-endian standard none
! network (= big-endian) standard none

pythonstruct包源碼:

def pack(fmt, *args): # known case of _struct.pack
    """ Return string containing values v1, v2, ... packed according to fmt. """
    return ""
  
def unpack(fmt, string): # known case of _struct.unpack
    """
    Unpack the string containing packed C structure data, according to fmt.
    Requires len(string) == calcsize(fmt).
    """
    pass

# 第一個參數用上述表格內的fmt格式表示字符串
# 其他參數*args爲自己要進行轉爲字節串的值

轉義爲short型整數:

struct.unpack('<hh', bytes(b'\x01\x00\x00\x00'))  ==>  (1, 0)
# fmt的"<hh"  代表:little-endian(寄存器數字的存儲方式,小的在前),兩個雙字節的整型integer(一個轉成兩個數,每個佔了兩個字節,不足位置補的是0)

轉義爲long型整數:

struct.unpack('<L', bytes(b'\x01\x00\x00\x00'))  ==>  (1,)
# 轉成一個四字節的整型long

4.整數to字節串

轉爲兩個字節:

struct.pack('<HH', 1,2)  ==>  b'\x01\x00\x02\x00'
# 將兩個值1和2,轉換爲雙字節表示的字節串。(如:1 >>> b'\x01\x00'  2 >>> b'\x02\x00')

轉爲四個字節:

struct.pack('<LL', 1,2)  ==>  b'\x01\x00\x00\x00\x02\x00\x00\x00'
# 將兩個值1和2,轉換爲四字節表示的字節串(如:整數1可表示爲 b'\x01\x00\x00\x00')

5.整數to字符串

直接用函數

str(100)

6.字符串to字節串

  • decodeencode區別

decode函數是重新解碼,把CT字符串所顯示的69dda8455c7dd425【每隔兩個字符】解碼成十六進制字符\x69\xdd\xa8\x45\x5c\x7d\xd4\x25

CT = '69dda8455c7dd425'
print "%r"%CT.decode('hex')

encode函數是重新編碼,把CT字符串所顯示的69dda8455c7dd425【每個字符】編碼成acsii值,ascii值爲十六進制顯示,佔兩位。執行下列結果顯示36396464613834353563376464343235等價於將CT第一個字符’6’編碼爲0x36h 第二個字符’9’編碼爲0x39h

CT='69dda8455c7dd425'
print "%r"%CT.encode('hex')

可以理解爲:decode解碼,字符串變短一半,encode編碼,字符串變爲兩倍長度

python2和python3編碼有區別,這裏注意區分

decode(‘ascii’)解碼爲字符串Unicode格式。輸出帶有’u’
encode(‘ascii’),編碼爲Unicode格式,其實python默認處理字符串存儲就是Unicode,輸出結果估計和原來的字符串一樣。

字符串編碼爲字節碼:

'12abc'.encode('ascii')  ==>  b'12abc'

數字或字符數組:

bytes([1,2, ord('1'),ord('2')])  ==>  b'\x01\x0212'

16進制字符串:

bytes().fromhex('010210')  ==>  b'\x01\x02\x10'

16進制字符串:

bytes(map(ord, '\x01\x02\x31\x32'))  ==>  b'\x01\x0212'

16進制數組:

bytes([0x01,0x02,0x31,0x32])  ==>  b'\x01\x0212'

7.字節串to字符串

字節碼解碼爲字符串:

bytes(b'\x31\x32\x61\x62').decode('ascii')  ==>  12ab

字節串轉16進製表示,夾帶ascii:

str(bytes(b'\x01\x0212'))[2:-1]  ==>  \x01\x0212

字節串轉16進製表示,固定兩個字符表示:

str(binascii.b2a_hex(b'\x01\x0212'))[2:-1]  ==>  01023132

字節串轉16進制數組:

[hex(x) for x in bytes(b'\x01\x0212')]  ==>  ['0x1', '0x2', '0x31', '0x32']

問題:什麼時候字符串前面加上’r’、’b’、’r’,其實官方文檔有寫。我認爲在Python2中,r和b是等效的。

The Python 2.x documentation:

A prefix of ‘b’ or ‘B’ is ignored in Python 2; it indicates that the literal should become a bytes literal in Python 3 (e.g. when code is automatically converted with 2to3). A ‘u’ or ‘b’ prefix may be followed by an ‘r’ prefix.
‘b’字符加在字符串前面,對於python2會被忽略。加上’b’目的僅僅爲了兼容python3,讓python3以bytes數據類型(0~255)存放這個字符、字符串。

The Python 3.3 documentation states:

Bytes literals are always prefixed with ‘b’ or ‘B’; they produce an instance of the bytes type instead of the str type. They may only contain ASCII characters; bytes with a numeric value of 128 or greater must be expressed with escapes.
數據類型byte總是以’b’爲前綴,該數據類型僅爲ascii。

下面是stackflow上面一個回答。我覺得不錯,拿出來跟大家分享

In Python 2.x

Pre-3.0 versions of Python lacked this kind of distinction between text and binary data. Instead, there was:

  • unicode = u’…’ literals = sequence of Unicode characters = 3.x str
  • str = ‘…’ literals = sequences of confounded bytes/characters
    Usually text, encoded in some unspecified encoding.
    But also used to represent binary data like struct.pack output.

Python 3.x makes a clear distinction between the types:

  • str = ‘…’ literals = a sequence of Unicode characters (UTF-16 or UTF-32, depending on how Python was compiled)
  • bytes = b’…’ literals = a sequence of octets (integers between 0 and 255)

二、 Python字節串詳解

1.字節串概念理解

  • 存儲以字節爲單位的數據
  • 字節串是不可變的字節序列
  • 字節是 0~255 之間的整數

2.創建字節串

# 創建空字節串的字面值
b'' 
b""
b''''''
b""""""
B''
B""
B''''''
B""""""
# 創建非空字節串的字面值
b'ABCD'
b'\x41\x42'
b'hello Jason'

3.字節串的構造函數

  • bytes() 生成一個空的字節串 等同於 b''
  • bytes(整型組成的可迭代對象) 用可迭代對象初始化一個字節串,不能超過255
  • bytes(整數n) 生成 n 個值爲零的字節串
  • bytes(字符串, encoding='utf-8') 用字符串的轉換編碼生成一個字節串
a = bytes()  # b''
b = bytes([10,20,30,65,66,67])  # b'\n\x14\x1eABC'
c = bytes(range(65,65+26))  # b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
d = bytes(5)  # b'\x00\x00\x00\x00\x00'
e = bytes('hello 中國','utf-8')  # b'hello \xe4\xb8\xad\xe5\x9b\xbd'

4.字節串的運算

  • + += * *=
  • < <= > >= == !=
  • in / not in 只能對整型數進行操作
  • 索引/切片
b = b'abc' + b'123'  # b=b'abc123'
b += b'ABC'    # b=b'abc123ABC'
b'ABD' > b'ABC'  # True
b'a'*4   # b'aaaa'
b = b'ABCD'
65 in b    # True
b'A' in b  # True

5.bytesstr 的區別

  • bytes 存儲字節(0-255)
  • str 存儲Unicode字符(0-65535)

6.bytesstr 轉換

  • strbytes
    b = s.encode('utf-8')
  • bytesstr
    s = b.decode('utf-8')

三、 字節數組

可變的字節序列

1.創建字構造函數

  • bytearray() 生成一個空的字節串 等同於 bytearray(b'')
  • bytearray(整型可迭代對象) 用可迭代對象初始化一個字節串,不能超過255
  • bytearray(整數n) 生成 n 個值爲零的字節串
  • bytearray(字符串, encoding='utf-8') 用字符串的轉換編碼生成一個字節串
a = bytearray() # bytearray(b'')
b = bytearray(5) # bytearray(b'\x00\x00\x00\x00\x00')
c = bytearray([1,2,3,4]) # bytearray(b'\x01\x02\x03\x04')

2.字節數組的運算

  • + += * *=
  • < <= > >= == !=
  • in / not in 只能對整型數進行操作
  • 索引/切片

3.字節數組的方法

  • B.clear() 清空字節數組
  • B.append(n) 追加一個字節(n爲0-255的整數)
  • B.remove(value) 刪除第一個出現的字節,如果沒有出現,則產生ValueError錯誤
  • B.reverse() 字節的順序進行反轉
  • B.decode(encoding='utf-8') # 解碼
  • B.find(sub[, start[, end]]) 查找

鳴謝:(https://www.kancloud.cn/hx78/python/450119)
(https://www.jianshu.com/p/5bb986772ef8)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章