VB编码, Gamma编码, Delta编码

VB编码, Gamma编码, Delta编码


学习笔记,记录VB编码, Gamma编码, Delta编码的自动计算代码。

1. VB code

例:十进制数824使用vb code进行编码
(1)将十进制数824转化为十六进制338
(2)将16进制中的每一位数当成单个十进制数后转换为二进制的四位数,然后连接起来0011 0011 1000
(3)去除开头所有0,得到1100111000
(4)通过在开头加0的方式,将字符串拆分为7个一组,得到0000110和0111000
(5)在最后一个7位数前面加1,其余不代表终止的7位数前面加0,凑成8个一组
(6)最终结果为:
00000110 10111000

编码代码,输入原始数字输出字符串:

def vb_encoding(ori_data):
    code = hex(ori_data)[2:]
    result = ''
    for i in code:
        temp = bin(int(i,10))[2:]
        if len(temp) < 4:
            temp = '0'*(4-len(temp)) + temp
        result = result + temp
    # 去除开头的0
    result = result.lstrip('0')
    # 补全到7的倍数
    if len(result) % 7 != 0:
        result = '0'*(7-len(result) % 7) + result
    # 拆分为多行
    result_list = []
    result_list.append('0' + result[:7])
    while len(result) != 7:
        result = result[7:]
        result_list.append('0' + result[:7])
    result_list[-1] = '1' + result_list[-1][1:]
    return result_list

解码代码,输入二进制字符串得到多个原始数字:

def vb_decoding(bin_data):
    bin_data = bin_data.replace(" ", "")
    result = []
    while len(bin_data) != 0:
        t = 0
        while bin_data[t*8] != '1':
            t += 1
        # 获取当前数字的字符串
        if len(bin_data) == (t+1)*8:
            cut = bin_data
            bin_data = ''
        else:
            cut = bin_data[:(t+1)*8]
            bin_data = bin_data[(t+1)*8:]
        # 开始还原数字
        code = []
        for i in range(len(cut)//8-1):
            code.append(cut[i*8: (i+1)*8])
        code.append(cut[-8:])
        code = list(map(lambda x:x[1:], code))
        code = ''.join(code)
        code = code.lstrip('0')
        if len(code) % 4 != 0:
            code = '0' * (4 - len(code) % 4) + code
        temp_bin = []
        for i in range(len(code)//4-1):
            temp_bin.append(code[i*4: (i+1)*4])
        temp_bin.append(code[-4:])
        temp_bin = list(map(lambda x:str(int(x,2)), temp_bin))
        number = int(''.join(temp_bin), 16)
        result.append(number)
    return result

2. Gamma(γ) code

Gamma编码
对数字k
(1) kd = (log2(K))向下取整
(2) kr = K - 2^kd
kd使用unary表示,即在用kd个1加上一个0
kr使用binary表示,即用二进制编码表示kr

编码代码,输入原始数字输出字符串:

def gamma_encoding(ori_data):
    kd = math.floor(math.log2(ori_data))
    kr = ori_data - 2**kd
    result = '1'*kd+'0'+bin(kr)[2:]
    return result

解码代码,输入二进制字符串得到多个原始数字:

def gamma_decoding(bin_data):
    bin_data = bin_data.replace(" ", "")
    number_list = []
    while len(bin_data) != 0:
        index_of_zero = None
        # 找到第一个0的位置
        for i in range(len(bin_data)):
            if bin_data[i] == '0':
                index_of_zero = i
                break
        if index_of_zero == None:
            return "error string"
        # 如果第一个就是0
        if index_of_zero == 0:
            number_list.append(1)
            bin_data = bin_data[1:]
        # 否则
        else:
            bin_data = bin_data[index_of_zero + 1:]
            kd = index_of_zero
            tran_kr = bin_data[:kd]
            kr = int(tran_kr, 2)
            bin_data = bin_data[kd:]
            ori_num = 2 ** kd + kr
            number_list.append(ori_num)
    return number_list

3. Delta(δ) code

在Gamma编码的基础上,对kd再进行一次gamma编码得到kdd与kdr,从而进一步缩短编码的长度。

编码代码,输入原始数字输出字符串:

def delta_encoding(ori_data):
    kd = math.floor(math.log2(ori_data))
    kr = ori_data - 2**kd
    tran_kr = bin(kr)[2:]
    # 因为后面kd要+1,所以这里先编码完最后一段
    if len(tran_kr) < kd:
        tran_kr = '0'*(kd-len(tran_kr)) + tran_kr
    
    kd = kd + 1
    kdd = math.floor(math.log2(kd))
    kdr = kd - 2**kdd
    
    tran_kdd = '1'*kdd + '0'
    tran_kdr = bin(kdr)[2:]
    if len(tran_kdr) < kdd:
        tran_kdr = '0'*(kdd-len(tran_kdr)) + tran_kdr
    
    result = tran_kdd + ' ' + tran_kdr + ' ' + tran_kr
    #print("kdd:", kdd, ", kdr:", kdr, ", kd:",kd,", kr:", kr)
    return result
    

解码代码,输入二进制字符串得到多个原始数字:

def delta_decoding(bin_data):
    bin_data = bin_data.replace(" ", "")
    number_list = []
    while len(bin_data) != 0:
        index_of_zero = None
        # 找到第一个0的位置
        for i in range(len(bin_data)):
            if bin_data[i] == '0':
                index_of_zero = i
                break
        if index_of_zero == None:
            return "error string"
        # 如果第一个就是0
        if index_of_zero == 0:
            number_list.append(1)
            bin_data = bin_data[1:]
        # 否则
        else:
            bin_data = bin_data[index_of_zero + 1:]
            kdd = index_of_zero
            tran_kdr = bin_data[:kdd]
            kdr = int(tran_kdr,2)
            bin_data = bin_data[kdd:]
            kd = 2**kdd + kdr - 1
            tran_kr = bin_data[:kd]
            kr = int(tran_kr,2)
            bin_data = bin_data[kd:]
            ori_num = 2**kd + kr
            number_list.append(ori_num)
    return number_list

猜你喜欢

转载自blog.csdn.net/starvapour/article/details/111415936