Hướng dẫn bit manipulation python - Python thao tác bit

Dưới đây là một số thông tin và mục tiêu liên quan đến thao tác bit Python, thao tác nhị phân.

Một số nhiệm vụ bao gồm:

  • Biến "11011000111101 ..." thành byte, (đệm trái hoặc phải, 0 hoặc 1,) và ngược lại.
  • Phạm vi cắt các bit
  • Xoay bit, được giải quyết bởi bit. Đó là, giả sử: "Xoay bit 13-17, quấn quanh các cạnh" hoặc, "Xoay bit 13-17, mất bit ở một bên, đặt tất cả các bit mới thành 0."
  • Tương tự, các vùng hoàn nguyên của bit, áp dụng logic cho các vùng của bit, v.v.,.
  • Chuyển đổi endianness, với các kích thước khối khác nhau.
  • Áp dụng các hoạt động trong các nhóm khối: Ex: Áp dụng XOR 10101 (5 bit) nhiều lần trên một trường.

Các thư viện có liên quan bao gồm:

  • CTYPES - Một thư viện chức năng nước ngoài cho Python - Python v2.7.3 Tài liệu - một phần của thư viện tiêu chuẩn

  • Bitarray - Mảng hiệu quả của Booleans - C Tiện ích mở rộng

  • Python -bitstring - Một mô -đun Python để giúp bạn quản lý các bit của mình. - Lưu trữ dự án Google

  • BITSTRUCT - Mô -đun này thực hiện chuyển đổi giữa các giá trị python và các cấu trúc trường bit C được biểu thị dưới dạng bytearrays python.

Một số mã đơn giản là tại ASPN: thao tác trường bit.

Dưới đây là một số ví dụ khác.

Thao tác

Đến số nguyên.

   1 >>> print int('00100001', 2)
   2 33

Đến chuỗi hex. Lưu ý rằng bạn không cần sử dụng các bit x8.

   1 >>> print "0x%x" % int('11111111', 2)
   2 0xff
   3 >>> print "0x%x" % int('0110110110', 2)
   4 0x1b6
   5 >>> print "0x%x" % int('0010101110101100111010101101010111110101010101', 2)
   6 0xaeb3ab57d55

Để nhân vật. 8 bit tối đa.

   1 >>> chr(int('111011', 2))
   2 ';'
   3 >>> chr(int('1110110', 2))
   4 'v'
   5 >>> chr(int('11101101', 2))
   6 '\xed'

Ký tự cho số nguyên, nhưng không phải là chuỗi của 1 và 0.

   1 >>> int('01110101', 2)
   2 117
   3 >>> chr(int('01110101', 2))
   4 'u'
   5 >>> ord('u')
   6 117

Bit cá nhân.

   1 >>> 1 << 0
   2 1
   3 >>> 1 << 1
   4 2
   5 >>> 1 << 2
   6 4
   7 >>> 1 << 3
   8 8
   9 >>> 1 << 4
  10 16
  11 >>> 1 << 5
  12 32
  13 >>> 1 << 6
  14 64
  15 >>> 1 << 7
  16 128

Tóm tắt biến đổi

Chuỗi đến số nguyên:

  • "1011101101": int (str, & nbsp; 2)

  • "M": ord (str)

  • "0xdecafbad": int (str, & nbsp; 16) (được biết là làm việc trong Python 2.4)

  • "decafbad": int (str, & nbsp; 16) (được biết là làm việc trong Python 2.4)

Số nguyên cho chuỗi:

  • "1011101101": tích hợp với Python 3 (xem bên dưới)

  • "M": chr (str)

  • "0xdecafbad": Hex (Val)

  • "decafbad": "%x" & nbsp;%& nbsp; val

Chúng tôi vẫn bị bỏ lại mà không có kỹ thuật sản xuất chuỗi nhị phân và các chuỗi hex decyphing.

Chuỗi hex để số nguyên

Sử dụng loại INT với đối số cơ sở:

   1 >>> int('0xff',16)
   2 255
   3 >>> int('d484fa894e',16)
   4 912764078414

Không sử dụng các lựa chọn thay thế sử dụng Eval. Eval sẽ thực thi mã được truyền cho nó và do đó có thể thỏa hiệp bảo mật chương trình của bạn.

Số nguyên vào chuỗi bin

Python 3 hỗ trợ các tác phẩm nhị phân (ví dụ: 0b10011000) và có hàm bin (). Cho các phiên bản cũ hơn:

   1 >>> def bin(a):
   2         s=''
   3         t={'0':'000','1':'001','2':'010','3':'011',
   4            '4':'100','5':'101','6':'110','7':'111'}
   5         for c in oct(a)[1:]:
   6                 s+=t[c]
   7         return s

hoặc tốt hơn:

   1 def bin(s):
   2     return str(s) if s<=1 else bin(s>>1) + str(s&1)

Số nguyên Python

Từ trang "Tham chiếu ngôn ngữ Python" trên mô hình dữ liệu:

"Các số nguyên (int) Các số này thể hiện các số trong một phạm vi không giới hạn, chỉ có bộ nhớ (ảo) chỉ có sẵn. Với mục đích hoạt động thay đổi và mặt nạ, một biểu diễn nhị phân được giả định và các số âm được biểu diễn trong một biến thể của 2 Ảo tưởng về một chuỗi vô hạn các bit dấu hiệu kéo dài sang trái. "

Trước Python 3.1, không có cách nào dễ dàng để xác định làm thế nào Python đại diện cho một số nguyên cụ thể trong nội bộ, tức là có bao nhiêu bit được sử dụng. Python 3.1 thêm một phương thức bit_length () vào loại int thực hiện chính xác điều đó.

Trừ khi bạn biết rằng bạn đang làm việc với các số ít hơn một độ dài nhất định, ví dụ: các số từ các mảng số nguyên, ca làm việc, xoay, v.v. có thể cho kết quả không mong muốn.

Số lượng bộ bit cao nhất là công suất cao nhất 2 nhỏ hơn hoặc bằng số nguyên đầu vào. Điều này giống như số mũ của biểu diễn điểm nổi của số nguyên và còn được gọi là "Cơ sở số nguyên số nguyên 2". (Ref.1)

Trong các phiên bản trước 3.1, cách dễ nhất để xác định bộ bit cao nhất là*:

* Có một cuộc thảo luận dài về chủ đề này, và tại sao phương pháp này không tốt, trong "Vấn đề 3439" tại python.org: http://bugs.python.org/issue3439 Cuộc thảo luận này đã dẫn đến việc bổ sung bit_lengm () trong Python 3.1.

   1 import math
   2 
   3 hiBit = math.floor(math.log(int_type, 2))

Một đầu vào nhỏ hơn hoặc bằng 0 kết quả trong "Lỗi miền Math: Matherror: Math"

Phần "Tìm cơ sở nhật ký số nguyên 2 của một số nguyên" trên "Trang web Hacks Twiddling Bit" (ref.1) bao gồm một số phương thức để xác định giá trị này cho các số nguyên có độ lớn đã biết, có lẽ khi không có trình điều trị toán học. Phương pháp duy nhất thường áp dụng cho các số nguyên python có độ lớn không xác định là "cách rõ ràng" của việc đếm số lượng hoạt động thay đổi bitwise cần thiết để giảm đầu vào xuống 0.

Chiều dài bit của một số nguyên python

Bitlen () đếm độ dài bit thực tế của một số nguyên python, nghĩa là số lượng bit không khác cao nhất cộng với 1. 0, không có bit khác không, trả về 0. như mong đợi từ trích dẫn ở trên " Ảo tưởng về một chuỗi các bit dấu hiệu vô hạn kéo dài sang trái, "Một số âm ném máy tính vào một vòng lặp vô hạn.

Hàm có thể trả về bất kỳ kết quả nào lên đến chiều dài của số nguyên lớn nhất bộ nhớ máy tính của bạn có thể giữ được.

   1 def bitLen(int_type):
   2     length = 0
   3     while (int_type):
   4         int_type >>= 1
   5         length += 1
   6     return(length)
   7 
   8 for i in range(17):
   9      print(bitLen(i))
  10 
  11 

Phương pháp sử dụng mô -đun toán học nhanh hơn nhiều, đặc biệt là với số lượng lớn với hàng trăm chữ số thập phân.

bitLenCount()

Trong sử dụng chung, "số lượng bit" của số nguyên là số lượng bộ (1) bit, không phải độ dài bit của số nguyên được mô tả ở trên. Bitlen () có thể được sửa đổi để cũng cung cấp số lượng các bit được đặt trong số nguyên. Có các phương pháp nhanh hơn để có được số lượng bên dưới.

   1 >>> print "0x%x" % int('11111111', 2)
   2 0xff
   3 >>> print "0x%x" % int('0110110110', 2)
   4 0x1b6
   5 >>> print "0x%x" % int('0010101110101100111010101101010111110101010101', 2)
   6 0xaeb3ab57d55
0

Hoạt động trên số nguyên không xác định

Một số thủ tục không cần biết mức độ của một số nguyên để cho kết quả có ý nghĩa.

bitCount()

Quy trình và thông tin dưới đây đã được tìm thấy trong "Bit Twiddling Hacks" (ref.1)

  • - - - - - - - - - - - - - - - - - - - - - - - - -

Đếm bộ bit, cách của Brian Kernighan*

   1 >>> print "0x%x" % int('11111111', 2)
   2 0xff
   3 >>> print "0x%x" % int('0110110110', 2)
   4 0x1b6
   5 >>> print "0x%x" % int('0010101110101100111010101101010111110101010101', 2)
   6 0xaeb3ab57d55
1

Phương pháp này đi qua nhiều lần lặp như có các bit được đặt. Vì vậy, nếu chúng ta có một từ 32 bit chỉ có bộ bit cao, thì nó sẽ chỉ đi một lần qua vòng lặp.

* Ngôn ngữ lập trình C tái bản lần 2, Kernighan & Ritchie, 1988.

Don Knuth chỉ ra rằng phương pháp này đã được Peter Wegner xuất bản trong CACM 3 (1960), 322. Cũng được Derrick Lehmer phát hiện độc lập và xuất bản năm 1964 trong một cuốn sách do Beckenbach biên tập.

  • - - - - - - - - - - - - - - - - - - - - - - - - -

Đếm bộ bit, cách của Brian Kernighan*

Phương pháp này đi qua nhiều lần lặp như có các bit được đặt. Vì vậy, nếu chúng ta có một từ 32 bit chỉ có bộ bit cao, thì nó sẽ chỉ đi một lần qua vòng lặp.

   1 >>> print "0x%x" % int('11111111', 2)
   2 0xff
   3 >>> print "0x%x" % int('0110110110', 2)
   4 0x1b6
   5 >>> print "0x%x" % int('0010101110101100111010101101010111110101010101', 2)
   6 0xaeb3ab57d55
2

* Ngôn ngữ lập trình C tái bản lần 2, Kernighan & Ritchie, 1988.

   1 >>> print "0x%x" % int('11111111', 2)
   2 0xff
   3 >>> print "0x%x" % int('0110110110', 2)
   4 0x1b6
   5 >>> print "0x%x" % int('0010101110101100111010101101010111110101010101', 2)
   6 0xaeb3ab57d55
3

parityOf()

Don Knuth chỉ ra rằng phương pháp này đã được Peter Wegner xuất bản trong CACM 3 (1960), 322. Cũng được Derrick Lehmer phát hiện độc lập và xuất bản năm 1964 trong một cuốn sách do Beckenbach biên tập.

Kernighan và Knuth, chứng thực mạnh mẽ!bitcount & 1 is about the same speed as the parity function.

   1 >>> print "0x%x" % int('11111111', 2)
   2 0xff
   3 >>> print "0x%x" % int('0110110110', 2)
   4 0x1b6
   5 >>> print "0x%x" % int('0010101110101100111010101101010111110101010101', 2)
   6 0xaeb3ab57d55
4

lowestSet()

Điều này hoạt động vì mỗi phép trừ "mượn" từ 1 bit thấp nhất. Ví dụ:i & -i zeroes all but the lowest set bit. The bitLen() proceedure then determines its position. Obviously, negative numbers return the same result as their opposite. In this version, an input of 0 returns -1, in effect an error condition.

   1 >>> print "0x%x" % int('11111111', 2)
   2 0xff
   3 >>> print "0x%x" % int('0110110110', 2)
   4 0x1b6
   5 >>> print "0x%x" % int('0010101110101100111010101101010111110101010101', 2)
   6 0xaeb3ab57d55
5

Đó là một kỹ thuật tuyệt vời cho Python, vì kích thước của số nguyên không cần phải được xác định trước.

Từ "Bit Twiddling Hacks"

   1 >>> print "0x%x" % int('11111111', 2)
   2 0xff
   3 >>> print "0x%x" % int('0110110110', 2)
   4 0x1b6
   5 >>> print "0x%x" % int('0010101110101100111010101101010111110101010101', 2)
   6 0xaeb3ab57d55
6

Mã gần như giống hệt với bitcount (), ở trên, tính toán tính tương đương của một số nguyên, trả về 0 nếu có số lượng các bit đặt chẵn và -1 nếu có một số lẻ. Trên thực tế, việc đếm các bit và kiểm tra xem kết quả có kỳ lạ với Bitcount & 1 có cùng tốc độ với hàm chẵn lẻ hay không.

Để xác định số bit của bit thấp nhất được đặt trong một số nguyên, trong ký hiệu bổ sung twos I & -i không tất cả trừ bit được đặt thấp nhất. Kỷ yếu bitlen () sau đó xác định vị trí của nó. Rõ ràng, số âm trả về kết quả tương tự như đối diện của chúng. Trong phiên bản này, đầu vào là 0 trả về -1, có hiệu lực là một điều kiện lỗi.

   1 >>> print "0x%x" % int('11111111', 2)
   2 0xff
   3 >>> print "0x%x" % int('0110110110', 2)
   4 0x1b6
   5 >>> print "0x%x" % int('0010101110101100111010101101010111110101010101', 2)
   6 0xaeb3ab57d55
7

   1 >>> print "0x%x" % int('11111111', 2)
   2 0xff
   3 >>> print "0x%x" % int('0110110110', 2)
   4 0x1b6
   5 >>> print "0x%x" % int('0010101110101100111010101101010111110101010101', 2)
   6 0xaeb3ab57d55
8

Bit đơn

Các hoạt động một bit thông thường sẽ hoạt động trên bất kỳ số nguyên Python nào. Tùy thuộc vào lập trình viên để chắc chắn rằng giá trị của 'Offset' có ý nghĩa trong bối cảnh của chương trình.

  • Trường bit, ví dụ: cho các giao thức truyền thông

Nếu bạn cần giải thích các bit riêng lẻ trong một số dữ liệu, ví dụ: Một luồng byte Trong một giao thức truyền thông, bạn có thể sử dụng mô -đun CTYPES.

  • Người giới thiệu

Ref.1. "Bit Twiddling Hacks" của Sean Eron Anderson

  • http://graphics.stanford.edu/~seander/bithacks.html

ref.2. "Nghệ thuật ngôn ngữ hội" của Randall Hyde

http://webster.cs.ucr.edu/aoa/index.html Tập 4, Chương 5 "Thao tác bit"

  • Ref.3. Hacker's Delight

http://www.hackersdelight.org/

  • Liên kết nghiên cứu

  • Đây là loại điều chúng tôi đang tìm kiếm:

  • ASPN: Thao tác trường bit

  • Các mô -đun liên quan:

Mô -đun mảng - (phát hành với Python)