简化操作字节

bites的Python项目详细描述


咬伤

这个包提供了一个有用的类:Bs(bytes),可以帮助您在不编写大量愚蠢代码的情况下对字节执行多个操作。

安装

python3 -m pip install -U bites

为什么?

你不生气吗?

当您想执行一个简单的异或时

a=b'deadbeef'b=b'faceb00k'# Standardc=bytes(i^jfori,jinzip(a,b))# NumPyimportnumpyasnpc=(np.array([*a])^np.array([*b])).astype(np.uint8).tobytes()# Using this packagefrombitesimportBsc=bytes(Bs(a)^b)

需要简单加密时

m='the_plain_text_you_wanna_encrypt'e='the_secret_key'# Standardmb=m.encode()eb=e.encode()mbl=len(mb)ebl=len(eb)l=max(mbl,ebl)cb=bytes([mb[i%mbl]^eb[i%ebl]foriinrange(l)])# NumPyimportnumpyasnpmb=np.array(list(m.encode()))eb=np.array(list(e.encode()))print('You should repeat these arrays to the same length to use xor, '"and you gived up just because you don't know which method to use.\n"'You start googling then write down this code:')eb_=np.tile(eb,mb.size//eb.size+1)[:mb.size]cb=(mb^eb_).astype(np.uint8).tobytes()# elegant!# After you found this package:frombitesimportBscb=bytes(Bs(m)^e)# Or, if you don't want auto-repeating / padding, use n()cb=bytes(Bs(m)^Bs(e).n())# error!!!cb=bytes(Bs(m)^Bs(e).r())# repeat e to fit the length of mcb=bytes(Bs(m)^Bs(e).p(0))# pad e with 0s to fit the length of m
  • Bs默认情况下使用自动重复。
  • bs.r()显式指定使用自动重复。
  • bs.p(c)返回一个Bs,默认情况下将c填充到其他更长的操作数中。
  • bs.n()返回一个不会自动更改其长度的Bs对象。

用法

frombitesimportBsbs=Bs(1,2,3,4)bs# <Bs 4: [01, 02, 03, 04]>

创建bs

使用构造函数

这些行创建了相同的东西,输入参数将被展平并在range(0, 256)中自动转换为int。

# These all create `<Bs 4: [01, 02, 03, 04]>`Bs(1,2,3,4)Bs([1,2,3,4])Bs([[1],[2],[3,[4]]])Bs(256+1,256+2,256+3,256+4)Bs(1-256,2-256,3-256,4-256)Bs(bytes([1,2]),3,4)Bs('\x01',b'\x02',3,[4])Bs(Bs(1,2),[3],4)Bs(Bs(1,Bs(2)),Bs([3,Bs(4)]))

简单规则

  • int将替换为256的余数。
  • str将被编码成bytes(utf-8)。
  • Iterable将变平。
>>>Bs(range(5))<Bs5:[00,01,02,03,04]>>>>Bs([iforiinrange(256)ifi%3==i%7==0])<Bs13:[00,15,2a,3f,54,69,7e,93,a8,bd,d2,e7,fc]>>>>Bs(map(lambdan:n+3,range(5)))<Bs5:[03,04,05,06,07]>>>>Bs(range(0,3),range(10,13))<Bs6:[00,01,02,0a,0b,0c]>

从整数

# Integers will be considered as little endien>>>Bs.from_int(8192)<Bs2:[00,20]>>>>Bs.from_int(0x102030)<Bs3:[30,20,10]># Simply call `bs.rev()` if you want big endian>>>Bs.from_int(8192).rev()<Bs2:[20,00]>

来自十六进制字符串

# 'DE' is the first byte>>>Bs.from_hex('DEADBEEF')<Bs4:[de,ad,be,ef]># If the string starts with '0x', 'EF' will be the first byte>>>Bs.from_hex('0xDEADBEEF')<Bs4:[ef,be,ad,de]>>>>Bs.from_int(int('0xDEADBEEF',16))<Bs4:[ef,be,ad,de]>

来自位字符串

# The first bit is LSB>>>Bs.from_bin('00001111')<Bs1:[f0]># If the string starts with '0b', the first bit in the string is MSB>>>Bs.from_bin('0b00001111')<Bs1:[0f]>>>>Bs.from_int(int('0b00001111',2))<Bs1:[0f]># Notice that this will not be '00001111'>>>Bs.from_bin('0b00001111').bin()'11110000'

来自文件

print(Bs.load('/etc/passwd').str())

来自base64编码字节

Bs.from_base64('ZnVjaw==')

随机

>>>importstring>>>Bs.rand(8,cs=(string.ascii_lowercase+'0123456')).str()'c4u0epdn'>>>Bs.rand(8,cs=range(100)).hex()'4a334519435d1103'>>>Bs.rand(8,cs=string.hexdigits).str()'cb41fA41'

基本操作

切片

>>>bs=Bs(1,2,3,4)>>>bs<Bs4:[01,02,03,04]>>>>bs[:2]<Bs2:[01,02]>>>>bs[2]<Bs1:[03]>>>>bs[-1]<Bs1:[04]>>>>bs[::-1]<Bs4:[04,03,02,01]>>>>bs[::2]<Bs2:[01,03]>

设置bs切片的值

>>>bs=Bs(1,2,3,4)>>>bs<Bs4:[01,02,03,04]>>>>bs[:2]=0>>>bs<Bs4:[00,00,03,04]>>>>bs[:]=0>>>bs<Bs4:[00,00,00,00]>>>>bs[:]='1234'>>>bs<Bs4:[31,32,33,34]>>>>bs[:]='123'>>>bs<Bs4:[31,32,33,31]>>>>bs[:]='12345'>>>bs<Bs4:[31,32,33,34]>>>>bs[:]=Bs('12').n()# Error: cannot set values to range(0, 4): r=False, p=None, l=2>>>bs[:]=Bs('12').p(0)>>>bs<Bs4:[31,32,00,00]>

其他有用的方法
>>>bs=Bs('dead')>>>bs<Bs4:[64,65,61,64]># Repeat n times>>>bs.rep(2)<Bs8:[64,65,61,64,64,65,61,64]># Repeat to length>>>bs.repto(6)<Bs6:[64,65,61,64,64,65]># Pad to length>>>bs.padto(6,0)<Bs6:[64,65,61,64,00,00]># Append or concatenate>>>bs@'beef'<Bs8:[64,65,61,64,62,65,65,66]># Extend to length automatically>>>bs.extto(6)<Bs6:[64,65,61,64,64,65]># Explicit automatic repeating>>>bs.r().extto(6)<Bs6:[64,65,61,64,64,65]># Use automatic padding>>>bs.p(0).extto(6)<Bs6:[64,65,61,64,00,00]># Disable automatic extension>>>bs.n().extto(6)# Error

字节操作

对象为Bs的操作数将首先转换为Bs。如果长度不匹配,较短的将调用shorter_bs.extto(len(longer_bs)),以适应较长操作数的长度。

埃姆斯

>>>a=Bs.from_int(0x0a00)>>>a<Bs2:[00,0a]>>>>b=Bs.from_int(0x0b)>>>b<Bs1:[0b]>>>>a+b# b will be unrolled to <Bs 2: [0b, 0b]><Bs2:[0b,15]>>>>a+b.n()# Error: length not matched: (2, 1)>>>a-b<Bs2:[f5,ff]>>>>a*b<Bs2:[00,6e]>>>>a/b<Bs2:[00,00]>>>>a//b<Bs2:[00,00]>>>>a**b<Bs2:[00,00]>>>>a%b<Bs2:[00,0a]>

其他类型的二进制操作

另一个操作数也将首先转换为Bs,并自动重复以适应Bs的长度。

>>>cafe=Bs.from_hex('c01dcafe')>>>cafe<Bs4:[c0,1d,ca,fe]>>>>cafe+1<Bs4:[c1,1e,cb,ff]>>>>1+cafe<Bs4:[c1,1e,cb,ff]>>>>cafe+'糖'<Bs4:[a7,d0,60,e5]>>>>cafe+b'cafe'<Bs4:[23,7e,30,63]>>>>cafe+b'sugar'<Bs5:[33,92,31,5f,32]>>>>cafe+[1,2,3,4]<Bs4:[c1,1f,cd,02]>>>>cafe+range(5)<Bs5:[c0,1e,cc,01,c4]>>>>cafe.p(0)+[0]*6<Bs6:[c0,1d,ca,fe,00,00]>>>>cafe.bin()'00000011101110000101001101111111'>>>(cafe>>1).bin()# for each byte'00000110011100001010011011111110'>>>(cafe<<1).bin()# for each byte'00000001010111000010100100111111'

其他有用的方法
>>>bs=Bs(range(7))>>>bs<Bs7:[00,01,02,03,04,05,06]># Reverse>>>bs.rev()<Bs7:[06,05,04,03,02,01,00]># Roll>>>bs.roll(1)<Bs7:[06,00,01,02,03,04,05]>>>>bs.roll(-1)<Bs7:[01,02,03,04,05,06,00]>>>>bs.rjust(10,0xff)<Bs10:[ff,ff,ff,00,01,02,03,04,05,06]>>>>bs.ljust(10,0xff)<Bs10:[00,01,02,03,04,05,06,ff,ff,ff]># Iterate over every n bytes>>>bs.every()[<Bs1:[00]>,<Bs1:[01]>,<Bs1:[02]>,<Bs1:[03]>,<Bs1:[04]>,<Bs1:[05]>,<Bs1:[06]>]>>>bs.every(n=3)[<Bs3:[00,01,02]>,<Bs3:[03,04,05]>,<Bs1:[06]>]>>>bs.every(n=3,m=list)# map[[0,1,2],[3,4,5],[6]]>>>bs.every(n=3,m=int)[131328,328707,6]>>>bs.every(n=4,m=lambdai:i.asint(32))# with map[50462976,394500]>>>bs.every(4,list,lambdai:2ini)# filter before map[[0,1,2,3]]>>>bs.every(4,f=lambdai:2ini)# only filter[<Bs4:[00,01,02,03]>]

按位运算

在位上操作。

基本特性

#                       v MSB          v LSB>>>bs=Bs.from_bin('0b1111000011001100')>>>bs.bin()'0011001100001111'>>>bin(bs)'0b1111000011001100'>>>bs<Bs2:[cc,f0]>>>>bs.int()61644#                     v LSB          v MSB>>>bs=Bs.from_bin('1111000011001100')>>>bs.bin()'1111000011001100'>>>bin(bs)'0b11001100001111'>>>bs<Bs2:[0f,33]>>>>bs.int()13071

逻辑操作

>>>x=Bs.from_bin('1111000010101010')>>>(~x).bin()'0000111101010101'>>>y=Bs.from_bin('1'*16)>>>(x&y).bin()'1111000010101010'>>>(x|y).bin()'1111111111111111'>>>(x^y).bin()'0000111101010101'

在所有位上移位

>>>bs=Bs.from_bin('1100000000000001')>>>bs.shift(1).bin()'0110000000000000'>>>bs.shift(-1).bin()'1000000000000010'>>>bs.asint()-32765>>>bs.shift(-1,a=True).bin()# arithmetic'1000000000000011'>>>bs.shift(-2,a=True).bin()'0000000000000111'>>>bs.shift(-5,a=True).bin()'0000000000111111'>>>bs.shift(-100,a=True).bin()'1111111111111111'>>>bs=Bs.from_bin('0000000000000010')>>>bs.asint()16384>>>bs.shift(1,a=True).bin()'0000000000000000'>>>bs.shift(1,a=True).asint()0>>>bs.shift(-1,a=True).bin()'0000000000000100'>>>bs.shift(-1,a=True).asint()8192>>>bs.shift(-5,a=True).bin()'0000000001000000'>>>bs.shift(-5,a=True).asint()512>>>bs.shift(-100,a=True).bin()'0000000000000000'>>>bs.shift(-100,a=True).asint()0

其他有用的方法
>>>bs=Bs.from_bin('1100000000000001')>>>bs.revbits().bin()'1000000000000011'>>>bs.rollbits(1).bin()'1110000000000000'>>>bs.rollbits(-1).bin()'1000000000000011'>>>bs.bits()['1','1','0','0','0','0','0','0','0','0','0','0','0','0','0','1']>>>bs.bits(every=3)['110','000','000','000','000','1']>>>[bforbinbs.bits(every=3)iflen(b)==3]['110','000','000','000','000']

转换

到整数

>>>bs=Bs(0,0b10000000)>>>bs<Bs2:[00,80]>>>>bs.int()32768>>>int(bs)32768>>>bs.asint()-32768>>>bs.asint(8)0>>>bs.asint(16)-32768>>>bs.asint(32)32768>>>bs.asuint()32768>>>bs.asuint(8)0>>>bs=Bs.rand(32)>>>bs<Bs32:[51,2a,aa,dc,83,08,0c,84,10,43,5f,5c,db,de,97,17,55,49,4e,f3,89,b3,45,03,c1,98,77,fc,90,bd,50,6b]>>>>bs.asints(32)[-592827823,-2079586173,1549746960,395828955,-212973227,54899593,-59270975,1800453520]>>>bs.asuints(32)[3702139473,2215381123,1549746960,395828955,4081994069,54899593,4235696321,1800453520]

到字符串

>>>bs=Bs('las vegas')>>>bs<Bs9:[6c,61,73,20,76,65,67,61,73]>>>>bs.str()'las vegas'>>>str(bs)'las vegas'>>>bs.hex()'6c6173207665676173'>>>hex(bs)'0x73616765762073616c'>>>oct(bs)'0o346605473127304034660554'>>>bs.bin()'001101101000011011001110000001000110111010100110111001101000011011001110'>>>bin(bs)'0b11100110110000101100111011001010111011000100000011100110110000101101100'

其他

base64编码
>>>Bs('Las Vegas').base64()'TGFzIFZlZ2Fz'

哈希

>>>bs=Bs('Las Vegas')>>>bs.hash('md5')<Bs16:[05,c2,7b,f0,09,32,57,2d,e2,8b,f6,5a,05,39,ba,97]>>>>bs.hash('md5').hex()'05c27bf00932572de28bf65a0539ba97'>>>bs.hash('sha256')<Bs32:[2b,d2,5c,d9,60,ab,a8,b7,06,e2,b6,7f,2b,b3,8b,75,0e,e5,38,4b,0e,98,83,05,3e,bc,3b,89,ef,4d,de,f9]>>>>bs.hash('sha256').hex()'2bd25cd960aba8b706e2b67f2bb38b750ee5384b0e9883053ebc3b89ef4ddef9'# See what's available>>>importhashlib>>>hashlib.algorithms_guaranteed{'sha384','shake_128','sha3_256','sha3_512','md5','sha512','shake_256','sha3_384','sha1','sha3_224','blake2b','blake2s','sha256','sha224'}

命令管道

>>>Bs('stdin input').pipe('tr a-z A-Z').str()'STDIN INPUT'>>>Bs('stdin input').pipe('base64').pipe('tee /dev/stderr').pipe('base64 --decode').str()c3RkaW4gaW5wdXQ='stdin input'>>>print(Bs().pipe('ls').str())LICENSEREADME.mdbitesbites.egg-infobuilddistsetup.py

IPv4

>>>ip=Bs.from_ip4('192.168.1.1/16')>>>ip<Bs4:[00,00,a8,c0]>>>>ip.every(1,int)[0,0,168,192]>>>ip.ip4()'192.168.0.0'

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java没有主体的循环做什么?   java xtext项目中的默认内容辅助功能在哪里   通过相似(不相同)键的java分组映射   java Dagger 2 reinit singleton   检测图像中的矩形会产生不想要的结果(opencv,java)   Java方法调用与使用变量的性能比较   尝试使用hibernate连接到mysql时,java连接被拒绝   允许端口的java IP地址正则表达式   通过Socket实现java Android到PC的数据交换   java使用maven向类路径添加额外的配置文件夹   java我似乎无法从RMI存根获得socket工厂。为什么会这样?   java使用hibernate向数据库添加数据   java驱动程序对于Chromedriver不可执行   java编译错误。mysql。jdbc。驱动程序无法解析为变量