将二进制数切成五位数组

时间:2010-10-26 21:47:30

标签: python slice

是否有任何巧妙的技巧可以将二进制数分成python中的五位数组?

'00010100011011101101110100010111'=> ['00010','00110','10111',...]

编辑: 我想写一个密码/编码器,以便生成“易于通过手机阅读”的令牌。标准的base32编码具有以下缺点:

  • 可能产生意外的f *字
  • 使用混乱的字符,如“我”,“L”,“O”等字符(可能与0和1混淆)
  • 易于猜测的序列(“AAAA”,“AAAB”,......)

我能够在20行python中自己动手,谢谢大家。我的编码器不使用'I','L','O'和'U',结果序列很难猜测。

7 个答案:

答案 0 :(得分:6)

>>> a='00010100011011101101110100010111'
>>> [a[i:i+5] for i in range(0, len(a), 5)]
['00010', '10001', '10111', '01101', '11010', '00101', '11']

答案 1 :(得分:6)

>>> [''.join(each) for each in zip(*[iter(s)]*5)]
['00010', '10001', '10111', '01101', '11010', '00101']

或:

>>> map(''.join, zip(*[iter(s)]*5))
['00010', '10001', '10111', '01101', '11010', '00101']

[编辑]

Greg Hewgill提出了这个问题,如何处理两个尾随位?以下是一些可能性:

>>> from itertools import izip_longest
>>>
>>> map(''.join, izip_longest(*[iter(s)]*5, fillvalue=''))
['00010', '10001', '10111', '01101', '11010', '00101', '11']
>>>
>>> map(''.join, izip_longest(*[iter(s)]*5, fillvalue=' '))
['00010', '10001', '10111', '01101', '11010', '00101', '11   ']
>>>
>>> map(''.join, izip_longest(*[iter(s)]*5, fillvalue='0'))
['00010', '10001', '10111', '01101', '11010', '00101', '11000']

答案 2 :(得分:1)

另一种分组迭代的方法,来自itertools示例:

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

答案 3 :(得分:1)

根据您的评论,您实际上需要基本的32个字符串。

>>> import base64
>>> base64.b32encode("good stuff")
'M5XW6ZBAON2HKZTG'

答案 4 :(得分:1)

使用正则表达式怎么样?

>>> import re
>>> re.findall('.{1,5}', '00010100011011101101110100010111')
['00010', '10001', '10111', '01101', '11010', '00101', '11']

如果您的输入字符串包含您在分组中想要的换行符,这将会破坏。

答案 5 :(得分:1)

My question被这个重复了,所以我会在这里回答。

我使用Generators

为所有这类问题提供了更通用,更有效的答案
from itertools import islice
def slice_generator(an_iter, num):
    an_iter = iter(an_iter)
    while True:
        result = tuple(islice(an_iter, num))
        if not result:
           return
        yield result

所以对于这个问题,我们可以这样做:

>>> l = '00010100011011101101110100010111'
>>> [''.join(x) for x in slice_generator(l,5)]
['00010', '10001', '10111', '01101', '11010', '00101', '11']

答案 6 :(得分:0)

>>> l = '00010100011011101101110100010111'
>>> def splitSize(s, size):
...     return [''.join(x) for x in zip(*[list(s[t::size]) for t in range(size)])]
...  
>>> splitSize(l, 5)
['00010', '10001', '10111', '01101', '11010', '00101']
>>>