python编写进制间转化

题目:

1、进制之间转化

二进制转换成十进制:v = “0b1111011”

十进制转换成二进制:v = 18

八进制转换成十进制:v = “011”

十进制转换成八进制:v = 30

十六进制转换成十进制:v = “0x12”

十进制转换成十六进制:v = 87

2、请编写一个函数实现将IP地址转换成一个整数。

如 10.3.9.12 转换规则为:

 10           00001010

 3            00000011

 9            00001001

 12           00001100

再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?

# coding=utf-8

import math
import re
from functools import reduce

# 16进制的对应关系放入字典中查询
dict_16 = {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "A": 10, "B": 11, "C": 12,
           "D": 13, "E": 14, "F": 15}
dict_16_v = list(dict_16.values())
dict_16_k = list(dict_16.keys())


class Convert(object):
    """
    2进制、8进制、10进制,16进制之间转换
    """

    @staticmethod
    def convert(param: str, src: int, dst: int = 2):
        """
        :param param: 需要转化的源内容
        :param src: 变更前的进制
        :param dst: 需要变更为的进制,默认为2进制
        :return: 转化后的内容
        """
        reslut = 0
        # 检查输入的原编码是否正确start##############################
        src_who = whois(param)
        if not src:
            src_j = src_who
        # 输入param和输入源编码不一致
        if src < src_who:
            return 0
        # 输入不合法编码,或者转出编码为空
        if src_j and dst and src in (2, 8, 10, 16) and dst in (2, 8, 10, 16):
            if src_j == dst:
                return param
        # 检查输入的原编码是否正确end###############################
        param_1 = check(param)
        if param_1:
            param_2 = convert_2(param_1, src_j)
            if param_2:
                reslut = convert_other(param_2, dst)
        # 说明输入的只有0,返回原数
        else:
            return param
        return reslut

    @classmethod
    def ip_convert_2jinzhi(cls, param):
        """
        正则分析:ip三个点分隔一个0~255的4个数
        第一步:0~255拆分为三种情况
                1、百位:0,1-----十位不限制--------个位不限制
                2、百位=2--------十位=0到4---------个位不限制,
                3、百位=2--------十位=5------------个位[0-5]
        第二步: 1、[0-1]?\d{1,2}-----?说明百位在[0-1]中选0个或者1个,{1,2}表示十位和个位任意且至少有个位上有数
                 2、2[0-4]\d----------百位=2,十位[0-4],个位不限制
                 3、25[0-5]-----------百位2,十位5,个位[0-5]
        第三步:2和3提取公共部分后:2(5[0-5]|[0-4]\d)
                在合并上1:2(5[0-5]|[0-4]\d)|[0-1]?\d{1,2}  alis demo
        第四步:  (demo)(\.(demo)){3}拼接:(2(5[0-5]|[0-4]\d)|[0-1]?\d{1,2})(\.(2(5[0-5]|[0-4]\d)|[0-1]?\d{1,2})){3}
                  说明 :()括号的用处就是让其变成一个整体
                          \.表示实际输入的. 区分正则表达中. 表示任意一个字符
                          {3}表示有3个(\.(demo))部分,所以括号很重要
        :param param:需要转化的ip
        :return:
        """
        # 验证ip合法性
        regex = re.compile(r"(2(5[0-5]|[0-4]\d)|[0-1]?\d{1,2})(\.(2(5[0-5]|[0-4]\d)|[0-1]?\d{1,2})){3}")
        reslut = ""
        if regex.fullmatch(param):
            ip_list = param.split(".")
            # print(ip_list)
            temp = [Convert.convert(i, 10, 2) for i in ip_list]
            # print(temp)
            for j in temp:
                l = len(j)
                reslut += ((8 - l) * "0" + j)
            reslut = Convert.convert(reslut, 2, 10)
        else:
            return "你输入的ip不合法"
        return reslut


def whois(param):
    """判断是什么进制数据"""
    if list(filter(lambda x: x.isalpha(), param)):
        reslut = 16
    elif list(filter(lambda x: int(x) > 7, param)):
        reslut = 10
    elif list(filter(lambda x: int(x) > 1, param)):
        reslut = 8
    else:
        reslut = 2
    return reslut


def convert_2(param, src_j):
    """其他进制转化2进制"""
    if src_j not in (2, 8, 10, 16):
        return 0
    if src_j == 8:
        reslut = convert_8_2(param)
    elif src_j == 10:
        reslut = convert_10_2(param)
    elif src_j == 16:
        reslut = convert_16_2(param)
    else:
        reslut = param
    return reslut


def convert_other(param_2, dst_j):
    """2进制转化其他进制"""
    global dict_16
    global dict_16_k
    global dict_16_v
    reslut = ""
    if dst_j == 2:
        return param_2
    elif dst_j == 8:
        length = len(param_2)
        if length % 3:
            param_2 = (3 - length % 3) * "0" + param_2
        length = len(param_2)
        for i in range(0, length, 3):
            tmp = param_2[i:i + 3]
            reslut += str(int(reduce(lambda x, y: x + y, [int(w[1]) * math.pow(2, 2 - w[0]) for w in enumerate(tmp)])))
    elif dst_j == 10:
        length = len(param_2)
        reslut = str(
            int(reduce(lambda x, y: x + y, [int(w[1]) * math.pow(2, length - 1 - w[0]) for w in enumerate(param_2)])))
    else:
        length = len(param_2)
        if length % 4:
            param_2 = (4 - length % 4) * "0" + param_2
        length = len(param_2)
        for i in range(0, length, 4):
            tmp = param_2[i:i + 4]
            v = int(reduce(lambda x, y: x + y, [int(w[1]) * math.pow(2, 3 - w[0]) for w in enumerate(tmp)]))
            try:
                k = dict_16_k[dict_16_v.index(v)]
            except Exception as e:
                return 0
            reslut += k
    return reslut


def check(param):
    """检查入参,去掉前面无效的0"""
    reslut = ""
    for i in range(len(param)):
        if param[i] != "0":
            reslut = param[i:]
            break
    return reslut


def convert_8_2(param):
    """8进制转化2进制"""
    reslut = ""
    for i in param:
        try:
            tmp = int(i)
            if tmp > 7:
                return 0
        except ValueError as e:
            return 0
        tmp_res = ""
        while tmp:
            tmp_res += str(tmp % 2)
            tmp = tmp // 2
        tmp_res = (3 - len(tmp_res)) * "0" + tmp_res
        reslut += tmp_res
    reslut = check(reslut)
    return reslut


def convert_10_2(param):
    """10进制转化2进制"""
    reslut = ""
    try:
        tmp = int(param)
    except ValueError as e:
        return 0
    while tmp:
        reslut += str(tmp % 2)
        tmp = tmp // 2
    reslut = reslut[::-1]
    reslut = check(reslut)
    return reslut


def convert_16_2(param):
    """16进制转化2进制"""
    reslut = ""
    global dict_16
    for i in param:
        if i not in dict_16:
            return 0
        else:
            try:
                tmp_1 = dict_16[i]
            except Exception as e:
                return 0
        tmp = tmp_1
        tmp_res = ""
        while tmp:
            tmp_res += str(tmp % 2)
            tmp = tmp // 2
        if tmp_1 >= 10:
            tmp_res = tmp_res[::-1]
        tmp_res = (4 - len(tmp_res)) * "0" + tmp_res
        reslut += tmp_res
    reslut = check(reslut)
    return reslut


if __name__ == "__main__":
    res = Convert.convert("0101011011111101", 2, 16)
    # res = Convert.ip_convert_2jinzhi("255.255.255.255")
    print(res)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值