简化操作字节

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如何编写在请求体中接受XML的swagger API   java PrimeTable面临奇怪的错误   java如何检查数组中输入的用户是否为回文?   java如何删除JButton中文本周围的框?   java阻止直接访问JSF2中的xhtml文件   java如何获取定义方法的类的名称?   while loop如何让用户只需输入数字,然后在Java中重试?   从应用程序注册中列出azure存储帐户容器时,java受众验证失败   Java线程之间的多线程数据交换   java检查数组中是否存在重复的索引值?   java正则表达式从字符串中复制第二个URL   java如何从gradle项目依赖项中排除METAINF?   java如何将JLabel[]添加到JTable?   使用kotlin播放java音频(位于internet上的文件)