繁体   English   中英

在python中将原始二进制数据转换为自定义库的最佳方法是什么?

[英]What is the best way to convert raw binary data to a custom base in python?

我需要在处理之前将一些数据转换为以29为基数,并且正在使用以下方法:

import string

def datatobase(data, base):
    digs = string.digits + string.lowercase + string.uppercase
    if base > len(digs):
        return None
    digits = []
    x = int(data.encode("hex"), 16)
    while x:
        digits.append(digs[x % base])
        x /= base
    digits.reverse()
    return ''.join(digits)

问题是,这段小代码使我的程序变慢了太多,那么您将如何替换它呢?

仅针对基数29的自定义答案也将非常棒!

仅以29为底的int参数的解决方案。

递归:

s = '0123456789ABCDEFGHIJKLMNOPQRS'
def foo(n, s=s):
    if n < 29:
        return s[n]
    a, b = divmod(n, 29)
    return foo(a) + s[b]

常规

def foo(n, s=s):    
    x = ''
    while n >= 29:
        n, b = divmod(n, 29)
        x += s[b]
    x += s[n]
    return x[::-1]

如果您需要运行时...这个版本的速度是您的2.8倍,是@wwii的7%。

def bin2base29(n):
    s = '0123456789ABCDEFGHIJKLMNOPQRS'
    return s[n] if n < 29 else bin2base29(n / 29) + s[n % 29]

这是我从@wwii改编的方法的最终迭代和最快解决方案。

def bin2base29(n):
    s = '0123456789ABCDEFGHIJKLMNOPQRS'
    x = ''
    while n > 0:
        x = s[n % 29] + x
        n /= 29
    return x

如果您不反对使用第三方程序包, numpy.base_repr()是进行转换的一种非常方便的方法:

import os
import numpy

def datatobase(data, base):
    n = int(data.encode('hex'), 16)
    return numpy.base_repr(n, base)

>>> data = os.urandom(32)
>>> data
'\xfcBs\x82\xa8&\x18\xaaK\x8c$\x0fZ\x95\xc0aA%\x93\x91\xcc\x8a\xa8\xfdbk\xeb\x14\x15\x06\xbag'

>>> datatobase(data, 29)
'A8FB42CHLNEIOOE75AG773EKGBA69QP89PANAF8ROH2GA1LF3CC5H'
>>> datatobase(data, 16)
'FC427382A82618AA4B8C240F5A95C06141259391CC8AA8FD626BEB141506BA67'

您需要进行概要分析,以查看这是否为您的应用程序提供了足够的性能。

更新资料

分析显示numpy.base_repr()比OP的实现慢。 这是因为numpy实现基本上与Python中实现的算法相同,只是添加了可选的零填充。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM