3

Pythonで2進数を5桁のグループにスライスするための巧妙なトリックはありますか?

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

編集:「電話で読みやすい」トークンを生成するために、暗号/エンコーダーを作成したいと思います。標準の base32 エンコーディングには、次の欠点があります。

  • 偶発的な f*words を生成する可能性
  • 「I」、「L」、「O」などの紛らわしい文字を使用しています (0 と 1 と混同される可能性があります)
  • 推測しやすいシーケンス (「AAAA」、「AAAB」、...)

私は 20 行の Python で自分自身をロールバックすることができました。皆さんに感謝します。私のエンコーダーは「I」、「L」、「O」、および「U」を省き、結果のシーケンスを推測するのは困難です。

4

7 に答える 7

6
>>> a='00010100011011101101110100010111'
>>> [a[i:i+5] for i in range(0, len(a), 5)]
['00010', '10001', '10111', '01101', '11010', '00101', '11']
于 2010-10-26T21:52:27.357 に答える
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 によって提起されました。2 つの後続ビットをどうするか? 以下にいくつかの可能性を示します。

>>> 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']
于 2010-10-26T22:02:59.493 に答える
1

コメントによると、実際にはベース32の文字列が必要です。

>>> import base64
>>> base64.b32encode("good stuff")
'M5XW6ZBAON2HKZTG'
于 2010-10-26T22:54:28.557 に答える
1

正規表現を使ってみませんか?

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

ただし、入力文字列にグループ化に必要な改行が含まれている場合、これは機能しなくなります。

于 2010-10-26T23:17:47.507 に答える
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)
于 2010-10-26T21:52:56.537 に答える
1

私の質問はこれと重複していたので、ここで答えます。

ジェネレーターを使用して、この種のすべての質問に対して、より一般的でメモリ効率の高い回答を得ました

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']
于 2015-04-12T16:41:56.100 に答える
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']
>>> 
于 2010-10-26T21:52:12.783 に答える