2016-06-15 22 views
2

RESTベースのサービスをテストしており、入力の1つがテキスト文字列です。だから、私はPythonコードからランダムなUnicode文字列を送信しています。これまで私が送ったユニコード文字列はASCIIの範囲にあったので、すべてが機能しました。ランダムなユニコード文字列を取得する方法

今、私はASCII範囲を超えて文字を送信しようとしていますが、エンコードエラーが発生しています。ここに私のコードです。私はこのlinkを通り過ぎていて、それでも私の頭を包み込むことはできません。

# coding=utf-8 

import os, random, string 
import json 

junk_len = 512 
junk = (("%%0%dX" % junk_len) % random.getrandbits(junk_len * 8)) 

for i in xrange(1,5): 
    if(len(junk) % 8 == 0): 
     print u'decoding to hex' 
     message = junk.decode("hex") 

    print 'Hex chars %s' %message 
    print u' '.join(message.encode("utf-8").strip()) 

最初の行は問題なく印刷されますが、エンコードすることなくRESTサービスに送信することはできません。したがって、私がutf-8にそれをエンコードしようとしている2行目。これは、次のメッセージで失敗するコード行です。

UnicodeDecodeError: 'ascii' codec can't decode byte 0x81 in position 7: ordinal not in range(128)

答えて

1

これはいかがですか?他の人が言ったように

import random 

def random_utf8_string(n): 
    result=u"" 
    for i in xrange(n): 
     a = u"\\u%04x" % random.randrange(0x10000) 
     result = result + a.decode('unicode-escape') 
    return result 
+0

これは私のランダムな文字列生成を置き換えました。それは魅力のように働く。ありがとうございました。 – abhi

2

UTF-8は特定のビットパターンのみを許可します。コードではUTF-8を使用しているようですので、許可されたUTF-8パターンに準拠する必要があります。マルチバイトパターンで

1 byte: 0b0xxxxxxx 

2 byte: 0b110xxxxx 0b10xxxxxx 

3 byte: 0b1110xxxx 0b10xxxxxx 0b10xxxxxx 

4 byte: 0b11110xxx 0b10xxxxxx 0b10xxxxxx 0b10xxxxxx 

、最初のバイトは0とデータビットx続く主要1Sとパターン全体のバイト数を示します。先頭でないバイトはすべて、0b10xxxxxxの2つの先頭インジケータビット10と6つのデータビットxxxxxxと同じパターンに従います。

一般に、ランダムに生成されたバイトはこれらのパターンに従いません。ランダムにデータビットxしか生成できません。

+0

は、この説明のために十分に感謝することはできません。 – abhi

3

は、それはバイト配列が正しいことを持っているように、有効なランダムUTF-8バイトを作ることは非常に困難です。

すべての文字を0x0000から0x10FFFFまでの数字にマップするので、有効なUnicodeアドレスを得るために、その範囲内の数字をランダムに生成するだけです。乱数をunichar(またはPy3のchar)に渡すと、ランダムコードポイントの文字のUnicode文字列が返されます。

あなたがする必要があることは、有効なUTF-8シーケンスを作成するために、PythonにUTF-8にエンコードするよう求めることだけです。

Basic Multilingual Planeの戻り文字で0000-D7FFの範囲を使用すると、完全なUnicode範囲内に多くのギャップや印刷不可能な文字(フォントの制限による)が存在するため、システムによって印刷される可能性が高くなります。 UTF-8にエンコードすると、各文字に対して最大3バイトのシーケンスが生成されます。

平野ランダム

import random 

def random_unicode(length): 
    # Create a list of unicode characters within the range 0000-D7FF 
    random_unicodes = [unichr(random.randrange(0xD7FF)) for _ in xrange(0, length)] 
    return u"".join(random_unicodes) 

my_random_unicode_str = random_unicode(length=512) 
my_random_utf_8_str = my_random_unicode_str.encode('utf-8') 

ユニークなランダム

import random 

def unique_random_unicode(length): 
    # create a list of unique randoms. 
    random_ints = random.sample(xrange(0xD7FF), length) 

    ## convert ints into Unicode characters 
    # for each random int, generate a list of Unicode characters 
    random_unicodes = [unichr(x) for x in random_ints] 
    # join the list 
    return u"".join(random_unicodes) 

my_random_unicode_str = unique_random_unicode(length=512) 
my_random_utf_8_str = my_random_unicode_str.encode('utf-8') 
+0

あなたは@rossumによって与えられた4種類の有効なユニコードパターンをどのように説明していますか教えてください。 utf-8の文字列を取得できますか?説明はしっかりしていますが、サンプル/ xrangeがどのように有効なユニコード文字を生成するのかが分かりません – Jay

+1

4バイトUTF-8は説明しませんが、OPが望んでいないものです。それがどのように動作するの更新された説明を参照してください –

+0

はるかに明確に、ありがとう。 – Jay

関連する問題