基于Python设计的进制转换器,可以在10进制数、16进制数、2进制数之间相互转换。亮点:16进制数/2进制数可转换为有符号数整型。
缘由:某日在解码下位机传回来的数据时,发现找到的进制转换工具都是将16进制数当成无符号数转换的10进制,找不到有符号数的转换工具,遂,自己动手搓一个。于是诞生了这个。
本人不保证该作品没有bug,也没有经过严谨的测试验证,在任何情况下,无论因何种原因,本人均不承担因使用本程序或者代码所造成的任何直接、间接、特别、附带或间接损失的赔偿责任。
一、使用说明
- 双击 “
Base_Conversion.exe
” ,运行程序,会弹出程序窗口。 - 按照你的需求填写数据,点击计算即可显示结果。亮点:16进制数/2进制数可转换为有符号数整型。
- 程序界面如下:
URL:https://gitee.com/zerone_space/BaseConv
下载:https://gitee.com/zerone_space/crc16_calculator/releases/tag/v1.0.1-beta
二、源码使用[only for programmer]
1、安装python
2、下载源码
git clone https://gitee.com/zerone_space/BaseConv.git
cd BaseConv
3、测试、运行
python Base_Conversion.py
4、打包
4.1、安装虚拟环境
pip install pipenv
Tips:首次使用需要
pipenv
安装
4.2、进入虚拟环境
pipenv shell
4.3、在虚拟环境中安装 pyinstaller
打包工具
pip install pyinstaller -i https://pypi.doubanio.com/simple --trusted-host pypi.doubanio.com
Tips:每次重新打包都需要安装
4.4、在虚拟环境中使用pyinstaller
打包成可执行文件(.exe)
pyinstaller -F -w -i logo.ico ./src/Base_Conversion.py
4.5、完成打包,退出虚拟环境,再删除虚拟环境
exit
pipenv --rm
Tips:不删除虚拟环境也是可以的,这样下次重新打包,
则不需要重新安装pyinstaller
附录
from tkinter import *
from tkinter import messagebox
from tkinter.ttk import Combobox
import re
#font_str = "Times New Roman"
font_str = "阿里巴巴普惠体"
#font_str = "Source Han Sans CN"
def hexfmt(str):
str = re.sub(r'[^0-9a-fA-F]','',str)# 16进制数正则
if len(str)==0:
str='0'
print('HEX: '+str)
return str
def decfmt(str):
str = re.sub(r'[^-?\d+$]','',str)# 十进制数正则
if len(str)==0:
str="00"
print('DEC: '+str)
return str
def binfmt(str):
str = re.sub(r'[^0-1]','',str)# 二进制数正则
if len(str)==0:
str='00000000'
print('BIN: '+str)
return str
def sdec2int(intstr,signed):
#str = str.strip("-")
if signed== 1:
if intstr >=0:
if intstr < 128:
binstr = '{:08b}'.format(intstr)
elif intstr < 32768:
binstr = '{:016b}'.format(intstr)
elif intstr < 2147483648:
binstr = '{:032b}'.format(intstr)
else:
binstr = '{:064b}'.format(intstr)
else:
#print (intstr)
str_num = hex(intstr).strip("-")
#print (str_num)
abs = int(str_num,16)
if -128 <= intstr:
binstr = '{:08b}'.format(abs)
elif -32768 <= intstr:
binstr = '{:016b}'.format(abs)
elif -2147483648 <= intstr:
binstr = '{:032b}'.format(abs)
else:
binstr = '{:064b}'.format(abs)
#binstr = binstr.strip("-")
s =list(binstr)
width=len(s)
#s = list(bin(dec)[2:])
#print(s)
for i in range(len(s)):
if s[i]=='1':
s[i]='0'
else:
s[i]='1'
#print(s)
str =''
for i in s:
str += i
#print(str)
length=len(str)
binary=bin(int(str,2)+int('1',2))[2:]
if len(binary) > length:
binstr = binary[:length] # 如果超过了指定长度,则只返回前length位
else:
binstr = '0' * (length - len(binary)) + binary # 不足指定长度时补零
else:
if intstr < 256:
binstr = '{:08b}'.format(intstr)
elif intstr < 65536:
binstr = '{:016b}'.format(intstr)
elif intstr < 4294967296:
binstr = '{:032b}'.format(intstr)
else:
binstr = '{:064b}'.format(intstr)
return intstr,binstr
def shex2int(str,signed):
str = str.strip("-")
intstr = int(str,16)
if intstr < 256:
binstr = '{:08b}'.format(intstr)
elif intstr < 65536:
binstr = '{:016b}'.format(intstr)
elif intstr < 4294967296:
binstr = '{:032b}'.format(intstr)
else:
binstr = '{:064b}'.format(intstr)
#print ('fmt'+binstr)
if signed== 1:
s =list(binstr)
length=len(s)
#print('signed:',length)
#print(s)
if s[0] == '1':
result = intstr-2**length
else:
result = int(binstr,2)
else:
result = intstr
#print (binstr)
#print (result)
return result,binstr
def sbin2int(str,signed):
str = str.strip("-")
intstr = int(str,2)
if intstr < 256:
binstr = '{:08b}'.format(intstr)
elif intstr < 65536:
binstr = '{:016b}'.format(intstr)
elif intstr < 4294967296:
binstr = '{:032b}'.format(intstr)
else:
binstr = '{:064b}'.format(intstr)
#print ('fmt'+binstr)
if signed== 1:
s =list(binstr)
length=len(s)
#print('signed:',length)
#print(s)
if s[0] == '1':
result = intstr-2**length
else:
result = int(binstr,2)
else:
result = intstr
#print (binstr)
#print (result)
return result,binstr
class Application(Frame):
def __init__(self,master=None):
super().__init__(master)
self.master = master
self.pack()
self.CreatWidget()
# UI 组件
def CreatWidget(self):
self.label00 = Label(self,text='进制转换器',font=(font_str, 12, "bold"))
self.label00.grid(row=0,column=1)
# 数据输入框
self.label01 = Label(self,text='输入数据',font=(font_str, 10))
self.label01.grid(row=1,column=0)
self.instr = StringVar()
self.instr.set('0')
self.entry01 = Entry(self,textvariable=self.instr,width=50,font=(font_str, 10))
self.entry01.grid(row=1,column=1)
self.label04 = Label(self, text='16进制数(Hex)',font=(font_str, 10))
self.label04.grid(row=4,column=0)
self.hex = StringVar()
self.hex.set('00')
self.entry04 = Entry(self,textvariable=self.hex,width=50,font=(font_str, 10))
self.entry04.grid(row=4,column=1)
self.label05 = Label(self, text='10进制数(Dec)',font=(font_str, 10))
self.label05.grid(row=5,column=0)
self.dec = StringVar()
self.dec.set('0')
self.entry05 = Entry(self,textvariable=self.dec,width=50,font=(font_str, 10))
self.entry05.grid(row=5,column=1)
self.bin = StringVar()
self.bin.set('00000000')
self.label06 = Label(self, text='2_进制数(Bin)',font=(font_str, 10))
self.label06.grid(row=7,column=0)
self.entry06 = Entry(self, textvariable=self.bin,width=50,font=(font_str, 10))
self.entry06.grid(row=7, column=1)
self.result = StringVar()
self.result.set('0')
self.label07 = Label(self, text='有符号数(Dec)',font=(font_str, 10))
self.label07.grid(row=6,column=0)
self.entry07 = Entry(self, textvariable=self.result,width=50,font=(font_str, 10))
self.entry07.grid(row=6, column=1)
frm1= LabelFrame(self)
frm1.grid(row=2,column=1,rowspan=1,columnspan=1,sticky=W+E+N+S)
# 单选框,选择填入的数据所属进制类型(16、10、2进制)
self.selected = IntVar(value=1)
# 创建单选按钮组件
self.Ra1 = Radiobutton(frm1,text="10进制",variable=self.selected,value=1,font=(font_str,10))
self.Ra1.grid(row=2,column=0)
self.Ra2 = Radiobutton(frm1,text="16进制",variable=self.selected,value=2,font=(font_str,10))
self.Ra2.grid(row=2,column=1)
self.Ra3 = Radiobutton(frm1,text="2_进制",variable=self.selected,value=3,font=(font_str,10))
self.Ra3.grid(row=2,column=2)
# 创建复选框,选择填入的16进制/2进制数据是否是有符号数(如果输入的是10进制数,则自动根据‘负号’识别)
self.signed = IntVar(value=0)
# 创建复选按钮组件
self.CB1 = Checkbutton(frm1,text="有符号数",variable=self.signed,font=(font_str,10),command=self.cb)
self.CB1.grid(row=2,column=3)
self.combo = Combobox(frm1,values=['int8_t', 'int16_t', 'int32_t', 'int64_t'],width=6)
self.combo.grid(row=2,column=4)
self.combo.set('int8_t')
self.combo['state'] = 'disabled' # 设置为禁用状态
# 转换按钮
Button(self,text='开始转换',command=self.translate,font=(font_str, 10)).grid(row=3,column=1)
# 单击任意复选框时触发
def cb(self):
#print(self.signed.get())
if self.signed.get()==0:
self.combo['state'] = 'disabled' # 设置为禁用状态
else:
self.combo['state'] = 'enabled' # 设置为禁用状态
#print(self.combo.get())
# 点击“开始转换”按钮时调用
def translate(self):
str = self.instr.get()#self.entry01.get()
if re.match(r'^-.*$', str):#根据‘负号’自动识别有符号数,如果懒得打勾,可以在输入数据前面加一个"-"号,表明是有符号数
self.signed.set(1)
self.combo['state'] = 'enabled' # 设置为禁用状态
sel = self.selected.get()
signed = self.signed.get()
if sel == 1:# DEC
str = decfmt(str)
intstr = int(str,10)
self.instr.set(intstr)
elif sel == 2:# HEX
str = hexfmt(str)
self.instr.set(str)
intstr,binstr=shex2int(str,signed)
elif sel == 3:# BIN
str = binfmt(str)
intstr,binstr=sbin2int(str,signed)
self.instr.set(str)
else:
str='0'
intstr = int(str,10)
#print(intstr)#以上将不同进制数输入都转换为整型integer 处理
intstr,binstr = sdec2int(intstr,signed)
self.result.set(intstr)
self.bin.set(binstr)
intstr = int(binstr,2)
self.dec.set(intstr)
hexstr = hex(intstr)[2:]
self.hex.set(hexstr.upper())
length = len(binstr)
# 指示数据位宽(8bits 16bits 32bits 64bits)
if length==8:
self.combo.set('int8_t')
elif length==16:
self.combo.set('int16_t')
elif length==32:
self.combo.set('int32_t')
else:
self.combo.set('int64_t')
if __name__ == '__main__':
root = Tk()
sw = root.winfo_screenwidth()
sh = root.winfo_screenheight()
w = 600
h = 220
x = (sw-w)/2
y = (sh-h)/2
root.geometry("%dx%d+%d+%d" %(w,h,x,y))
root.title('进制转换工具')
root.resizable(0,0)
#root.iconbitmap('../logo.ico')
Application(master=root)
root.mainloop()