简化操作字节

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第三方库


热门话题
使用HQL查询的java Hibernate批更新   java AutoWiring steps与Spring Cucumber Serenity   JavaSpring启动测试用例不会加载所有组件   java RMI运行时何时断开客户端连接?   如果xml文件中缺少元素,如何在java中通过jaxb解组为该元素设置默认值   Mule3.9.0Java。util。ConcurrentModificationException:null   更改Java web服务响应的标头,而不进行Jackson转换   java在选择NEtbeans中的主类时存在歧义,尽管声明了公共类   java jawampa最大WebSock框架尺寸?   安卓 安卓x中定义的java add()。碎片应用程序。零碎交易   java如何设置日期的无效时间?   传递给persist:Profile的java分离实体   java Spring数据如何按子类中的属性排序   Java集合唯一键和唯一值   java按长度分割字符串,保持子字符串完整   集合Java 8流查找最大嵌套列表