Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中,将原始二进制数据转换为自定义基的最佳方法是什么?_Python_Binary_Int_Base - Fatal编程技术网

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

在python中,将原始二进制数据转换为自定义基的最佳方法是什么?,python,binary,int,base,Python,Binary,Int,Base,在处理之前,我需要将一些数据转换为base 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:

在处理之前,我需要将一些数据转换为base 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将是伟大的

Base 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]

如果你负责运行时。。。这个版本比你的快2.8倍,比@wwii快7%

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

如果您不反对使用第三方软件包,
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中实现的算法相同,并添加了可选的零填充。

这不是与OP的基本相同的算法吗?@Anton-但是,基本相同,这个答案包括OP算法没有的一些错误:)1)以29为基数的符号范围为
0-9
A-s
,2)以29为基数的单个“数字”的最大十进制值是28,而不是29。@Anton I将OP的问题视为性能问题-我试图提高性能,但没有进行比较。Bugs fixed,Thnx我认为这是的重复。如果你想快速完成这项工作,比如线性时间,那么我认为你需要将目标基数更改为2的幂,比如32或16。请给出一个你试图转换的
数据的示例。我不认为这是一个重复的问题,我已经阅读了页面bitsplit:在发布前指向,但这里我有一个真正的性能问题:)Antom wwii:我正在转换的数据并不重要,我还使用2的幂制作了我的脚本的早期版本(是的,这显然要快得多)。我现在真的需要使用base 29转换。
s
太短-它缺少
s
。另外,以29为基数的一位数的最大值是28,而不是29。@mhawke谢谢你说得对。我的例子都成功了,现在用28,29试一下……)您是如何衡量算法的性能的?它不比OP快29倍(此外,“29”似乎有点巧合!)@mhawke谢谢你的坚韧。我想我在时间上混合了重复或者习惯了很少的重复。我纠正了它,现在对我来说也更现实了。你有类似的数字吗?事实上,我发现OP是最快的。你的、我的和第二次世界大战的迭代都非常相似。谢谢,我想编辑我的问题,因为这就是我现在正在做的。我很快就会去看它是否真的更好。它比迭代法差40%。@wenzul:二进制字符串的长度对计时有很大影响。在短字符串上,迭代算法要快得多,而在长字符串(例如256字节)上,迭代算法实际上要慢得多。我发现OP的算法在大多数情况下是最快的。还有一件事,您可能没有包括从二进制数据字符串转换为int的成本-这在短字符串上大约值7%?
def bin2base29(n):
    s = '0123456789ABCDEFGHIJKLMNOPQRS'
    x = ''
    while n > 0:
        x = s[n % 29] + x
        n /= 29
    return x
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'