前置知识
python中各个进制的开头
二进制 : 0b
八进制 : 0o
十六进制 : 0x
进制转换函数 : bin() 转为2进制 oct() 转换为八进制的函数 hex() 转换为16进制的函数
ascii码和字符之间的转换 : chr('97') 码转为字符 字符转为码 ord('a')
进制转换脚本 :
def jinzhi(num_str, from_base, to_base): #传入的参数 需要数字 当前的进制 想要转换的进制try: #类型确定的容错# 确保输入是字符串类型shuru = int(str(num_str), from_base) # 先转为字符串if to_base == 2:return bin(shuru)[2:] # 切片去除前缀 2位elif to_base == 8:return oct(shuru)[2:]elif to_base == 16:return hex(shuru)[2:].upper()elif to_base == 10:return str(shuru) # 修正切片错误return Noneexcept (ValueError, TypeError):return None# 应该传入字符串类型的数字
print(jinzhi("123", 10, 2)) # 正确输出:1111011
print(jinzhi(123, 10, 2)) # 现在也能正常工作(因为内部做了转换)
进制转ascii字符串
每八个二进制代表一个ascii字符串 三个八进制代表一个
def bin_tostr(bin_str):ascii_str=''for i in range(0,len(bin_str),8): //进行遍历 步长是8a=bin_str[i,i+8] //进行 切片每八位一个asciiascii_str+=chr(int(a,2)) // 二进制转为 asciireturn ascii_strdef oct_tostr(oct_str):ascii_str=''for i in range(0.,len(oct_str),3):a=oct_str[i,i+3]ascii_str+=chr(int(a,8))return ascii_strdef hex_tostr(hex_str:str):if hex_str.startswith('0x'):hex_str=hex_str[2:]return bytes.fromhex(hex_str).decode('ascii') //16 进制可以直接转为 ascii 码 需要先进行字节流的转换 然后进行ascii解码
if __name__ == "__main__":a='0x68656c6c6f'print(hex_tostr(a))
但是上面这样写 如果我们给与的二进制的数大于8 多余的该怎么办 ?? 小于8该怎么办???
这个就是脚本撰写常考虑的 多减 少补问题
下面是改进的
def bin_tostr(bin_str:str,pad=True): #pad 就是是否开启下面的补 0 模式ascii_str=''lens=len(bin_str)//8 #表示向下取整这样就会筛下 大于8位的 这样后边我们还有进行处理#先处理 8的整数for i in range(0,lens):a=bin_str[i*8:(i+1)*8] # +1的目的是为了循坏的时候挨个向后推ascii_str+=chr(int(a,2))# 处理溢出或缺少的值 :remain=len(bin_str) % 8if remain>0 : #存在余数 if pad: # 当我们的输入值大于 8 或小于的时候 补 0 pad是true的时候进行补充 0 padded=bin_str[-remain:].ljust(8,'0') #ljust() 函数就是用来填充的 他对于字符串会自动进行左排序 然后根据第一个参数 进行右边填充ascii_str+=chr(int(padded,2)) #对填充的模式加到ascii 总和之后else:# 不补0 直接转换ascii_str+=chr(int(bin_str[-remain:],2))return ascii_str #return的 模式写的必须是这个地方 否则如果 str是正常的8的倍数就无法返回
改的地方 :pad 是是否开启补0模式
remain 有余数表示是对于 lens 是需要补充的 因为他是向下取整 不论是大于8的位数还是小于 对于 8的向下取整而言 都是需要进行补充的
练习是试着把 补 3位的 8进制也进行一下 补充