[英]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.