【问题标题】:How can I get a random unicode string我怎样才能得到一个随机的unicode字符串
【发布时间】:2016-10-16 22:57:39
【问题描述】:

我正在测试基于 REST 的服务,其中一个输入是文本字符串。所以我从我的 python 代码中发送随机的 unicode 字符串。到目前为止,我发送的 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 的第二行。这是失败并显示以下消息的代码行。

UnicodeDecodeError: 'ascii' 编解码器无法解码位置 0x81 字节 7:序数不在范围内(128)

【问题讨论】:

    标签: python-2.7 encoding utf-8 python-unicode


    【解决方案1】:

    正如其他人所说,制作有效的随机 UTF-8 字节非常困难,因为字节序列必须正确。

    由于 Unicode 将所有字符映射到 0x0000 和 0x10FFFF 之间的一个数字,因此只需在该范围内随机生成一个数字即可获得有效的 Unicode 地址。将随机数传递给 unichar(或 Py3 上的 char),将返回随机码点处字符的 Unicode 字符串。

    那么您需要做的就是让 Python 编码为 UTF-8 以创建有效的 UTF-8 序列。

    因为,在整个 Unicode 范围内有许多空白和不可打印字符(由于字体限制),使用 0000-D7FF 范围和 Basic Multilingual Plane 中的返回字符,您的系统更有可能打印这些字符.当编码为 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')
    

    【讨论】:

    • 您能否解释一下这是如何解释@rossum 给出的 4 种有效 unicode 模式的?我会得到任何可能的 utf-8 字符串吗?解释听起来很扎实,但我错过了 sample/xrange 如何仅生成/任何有效的 unicode 字符
    • 它不考虑 4 字节 UTF-8,但这不是 OP 想要的。查看有关其工作原理的更新说明
    【解决方案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
    

    在多字节模式中,第一个字节表示整个模式中的字节数,前导1,后跟0,数据位x。非前导字节都遵循相同的模式:0b10xxxxxx 具有两个前导指示位 10 和六个数据位 xxxxxx

    一般来说,随机生成的字节不会遵循这些模式。只能随机生成数据位x

    【讨论】:

      猜你喜欢
      • 2018-05-17
      • 1970-01-01
      • 1970-01-01
      • 2019-12-29
      • 2011-05-15
      • 2015-04-13
      • 1970-01-01
      • 1970-01-01
      • 2015-12-15
      相关资源
      最近更新 更多