import random def generate(length): # Generated from here (https://unicode-table.com/en/blocks/) with this vaguely horrible snippet: # Array.from(document.querySelectorAll("span.range")).map(node => node.textContent.split("—").map(x => x.trim())).map(([x, y]) => ` (0x${x}, 0x${y}),`).join("\n") include_ranges = [ (0x0000, 0x001F), (0x0020, 0x007F), (0x0080, 0x00FF), (0x0100, 0x017F), (0x0180, 0x024F), (0x0250, 0x02AF), (0x02B0, 0x02FF), (0x0300, 0x036F), (0x0370, 0x03FF), (0x0400, 0x04FF), (0x0500, 0x052F), (0x0530, 0x058F), (0x0590, 0x05FF), (0x0600, 0x06FF), (0x0700, 0x074F), (0x0750, 0x077F), (0x0780, 0x07BF), (0x07C0, 0x07FF), (0x0800, 0x083F), (0x0840, 0x085F), (0x0860, 0x086F), (0x08A0, 0x08FF), (0x0900, 0x097F), (0x0980, 0x09FF), (0x0A00, 0x0A7F), (0x0A80, 0x0AFF), (0x0B00, 0x0B7F), (0x0B80, 0x0BFF), (0x0C00, 0x0C7F), (0x0C80, 0x0CFF), (0x0D00, 0x0D7F), (0x0D80, 0x0DFF), (0x0E00, 0x0E7F), (0x0E80, 0x0EFF), (0x0F00, 0x0FFF), (0x1000, 0x109F), (0x10A0, 0x10FF), (0x1100, 0x11FF), (0x1200, 0x137F), (0x1380, 0x139F), (0x13A0, 0x13FF), (0x1400, 0x167F), (0x1680, 0x169F), (0x16A0, 0x16FF), (0x1700, 0x171F), (0x1720, 0x173F), (0x1740, 0x175F), (0x1760, 0x177F), (0x1780, 0x17FF), (0x1800, 0x18AF), (0x18B0, 0x18FF), (0x1900, 0x194F), (0x1950, 0x197F), (0x1980, 0x19DF), (0x19E0, 0x19FF), (0x1A00, 0x1A1F), (0x1A20, 0x1AAF), (0x1AB0, 0x1AFF), (0x1B00, 0x1B7F), (0x1B80, 0x1BBF), (0x1BC0, 0x1BFF), (0x1C00, 0x1C4F), (0x1C50, 0x1C7F), (0x1C80, 0x1C8F), (0x1CC0, 0x1CCF), (0x1CD0, 0x1CFF), (0x1D00, 0x1D7F), (0x1D80, 0x1DBF), (0x1DC0, 0x1DFF), (0x1E00, 0x1EFF), (0x1F00, 0x1FFF), (0x2000, 0x206F), (0x2070, 0x209F), (0x20A0, 0x20CF), (0x20D0, 0x20FF), (0x2100, 0x214F), (0x2150, 0x218F), (0x2190, 0x21FF), (0x2200, 0x22FF), (0x2300, 0x23FF), (0x2400, 0x243F), (0x2440, 0x245F), (0x2460, 0x24FF), (0x2500, 0x257F), (0x2580, 0x259F), (0x25A0, 0x25FF), (0x2600, 0x26FF), (0x2700, 0x27BF), (0x27C0, 0x27EF), (0x27F0, 0x27FF), (0x2800, 0x28FF), (0x2900, 0x297F), (0x2980, 0x29FF), (0x2A00, 0x2AFF), (0x2B00, 0x2BFF), (0x2C00, 0x2C5F), (0x2C60, 0x2C7F), (0x2C80, 0x2CFF), (0x2D00, 0x2D2F), (0x2D30, 0x2D7F), (0x2D80, 0x2DDF), (0x2DE0, 0x2DFF), (0x2E00, 0x2E7F), (0x2E80, 0x2EFF), (0x2F00, 0x2FDF), (0x2FF0, 0x2FFF), (0x3000, 0x303F), (0x3040, 0x309F), (0x30A0, 0x30FF), (0x3100, 0x312F), (0x3130, 0x318F), (0x3190, 0x319F), (0x31A0, 0x31BF), (0x31C0, 0x31EF), (0x31F0, 0x31FF), (0x3200, 0x32FF), (0x3300, 0x33FF), (0x3400, 0x4DBF), (0x4DC0, 0x4DFF), (0x4E00, 0x9FFF), (0xA000, 0xA48F), (0xA490, 0xA4CF), (0xA4D0, 0xA4FF), (0xA500, 0xA63F), (0xA640, 0xA69F), (0xA6A0, 0xA6FF), (0xA700, 0xA71F), (0xA720, 0xA7FF), (0xA800, 0xA82F), (0xA830, 0xA83F), (0xA840, 0xA87F), (0xA880, 0xA8DF), (0xA8E0, 0xA8FF), (0xA900, 0xA92F), (0xA930, 0xA95F), (0xA960, 0xA97F), (0xA980, 0xA9DF), (0xA9E0, 0xA9FF), (0xAA00, 0xAA5F), (0xAA60, 0xAA7F), (0xAA80, 0xAADF), (0xAAE0, 0xAAFF), (0xAB00, 0xAB2F), (0xAB30, 0xAB6F), (0xAB70, 0xABBF), (0xABC0, 0xABFF), (0xAC00, 0xD7AF), (0xD7B0, 0xD7FF), (0xD800, 0xDB7F), (0xDB80, 0xDBFF), (0xDC00, 0xDFFF), (0xE000, 0xF8FF), (0xF900, 0xFAFF), (0xFB00, 0xFB4F), (0xFB50, 0xFDFF), (0xFE00, 0xFE0F), (0xFE10, 0xFE1F), (0xFE20, 0xFE2F), (0xFE30, 0xFE4F), (0xFE50, 0xFE6F), (0xFE70, 0xFEFF), (0xFF00, 0xFFEF), (0xFFF0, 0xFFFF), (0x10000, 0x1007F), (0x10080, 0x100FF), (0x10100, 0x1013F), (0x10140, 0x1018F), (0x10190, 0x101CF), (0x101D0, 0x101FF), (0x10280, 0x1029F), (0x102A0, 0x102DF), (0x102E0, 0x102FF), (0x10300, 0x1032F), (0x10330, 0x1034F), (0x10350, 0x1037F), (0x10380, 0x1039F), (0x103A0, 0x103DF), (0x10400, 0x1044F), (0x10450, 0x1047F), (0x10480, 0x104AF), (0x104B0, 0x104FF), (0x10500, 0x1052F), (0x10530, 0x1056F), (0x10600, 0x1077F), (0x10800, 0x1083F), (0x10840, 0x1085F), (0x10860, 0x1087F), (0x10880, 0x108AF), (0x108E0, 0x108FF), (0x10900, 0x1091F), (0x10920, 0x1093F), (0x10980, 0x1099F), (0x109A0, 0x109FF), (0x10A00, 0x10A5F), (0x10A60, 0x10A7F), (0x10A80, 0x10A9F), (0x10AC0, 0x10AFF), (0x10B00, 0x10B3F), (0x10B40, 0x10B5F), (0x10B60, 0x10B7F), (0x10B80, 0x10BAF), (0x10C00, 0x10C4F), (0x10C80, 0x10CFF), (0x10E60, 0x10E7F), (0x11000, 0x1107F), (0x11080, 0x110CF), (0x110D0, 0x110FF), (0x11100, 0x1114F), (0x11150, 0x1117F), (0x11180, 0x111DF), (0x111E0, 0x111FF), (0x11200, 0x1124F), (0x11280, 0x112AF), (0x112B0, 0x112FF), (0x11300, 0x1137F), (0x11400, 0x1147F), (0x11480, 0x114DF), (0x11580, 0x115FF), (0x11600, 0x1165F), (0x11660, 0x1167F), (0x11680, 0x116CF), (0x11700, 0x1173F), (0x118A0, 0x118FF), (0x11A00, 0x11A4F), (0x11A50, 0x11AAF), (0x11AC0, 0x11AFF), (0x11C00, 0x11C6F), (0x11C70, 0x11CBF), (0x11D00, 0x11D5F), (0x12000, 0x123FF), (0x12400, 0x1247F), (0x12480, 0x1254F), (0x13000, 0x1342F), (0x14400, 0x1467F), (0x16800, 0x16A3F), (0x16A40, 0x16A6F), (0x16AD0, 0x16AFF), (0x16B00, 0x16B8F), (0x16F00, 0x16F9F), (0x16FE0, 0x16FFF), (0x17000, 0x187FF), (0x18800, 0x18AFF), (0x1B000, 0x1B0FF), (0x1B100, 0x1B12F), (0x1B170, 0x1B2FF), (0x1BC00, 0x1BC9F), (0x1BCA0, 0x1BCAF), (0x1D000, 0x1D0FF), (0x1D100, 0x1D1FF), (0x1D200, 0x1D24F), (0x1D300, 0x1D35F), (0x1D360, 0x1D37F), (0x1D400, 0x1D7FF), (0x1D800, 0x1DAAF), (0x1E000, 0x1E02F), (0x1E800, 0x1E8DF), (0x1E900, 0x1E95F), (0x1EE00, 0x1EEFF), (0x1F000, 0x1F02F), (0x1F030, 0x1F09F), (0x1F0A0, 0x1F0FF), (0x1F100, 0x1F1FF), (0x1F200, 0x1F2FF), (0x1F300, 0x1F5FF), (0x1F600, 0x1F64F), (0x1F650, 0x1F67F), (0x1F680, 0x1F6FF), (0x1F700, 0x1F77F), (0x1F780, 0x1F7FF), (0x1F800, 0x1F8FF), (0x1F900, 0x1F9FF), (0x20000, 0x2A6DF), (0x2A700, 0x2B73F), (0x2B740, 0x2B81F), (0x2B820, 0x2CEAF), (0x2CEB0, 0x2EBEF), (0x2F800, 0x2FA1F), (0xE0000, 0xE007F), (0xE0100, 0xE01EF), ] alphabet = [ chr(code_point) for current_range in include_ranges for code_point in range(current_range[0], current_range[1] + 1) ] return ''.join(random.choice(alphabet) for i in range(length))