From a770d4d8b0cc833c3e55709e655952bd8d225d14 Mon Sep 17 00:00:00 2001 From: dev Date: Wed, 7 Oct 2026 13:23:03 +0200 Subject: [PATCH] wordlist.dart: the random words of a key of words, as wordkey.Generate A port of List, CheckList, Generate and Bits of package wordkey of datekeys-go at 27a75ee (generate.go, spec 38.1), with the same checks in the same order and the same texts, each error a WordKeyException: - readWordList takes the file of a list that the app downloads or bundles only with the SHA-256 that wordListSha256 pins, "wordkey: the list "es" has the SHA-256 ..., not ...", and then reads it as List reads its text; - checkWordList refuses fewer than 2048 words, a word that is not one word of 3 letters or more once normalized, a rune that checkWords refuses, a character outside the alphabet of the language, which only the code gives (es: a to z, the five vowels with an acute accent, u with diaeresis and n with tilde, lower case, NFC), and two words that are one once normalized; - generateWords draws each index with randomIndex, as crypto/rand.Int, and draws again an index already drawn, so that the same bytes draw the same words as Go; what the RandomSource throws goes through; - wordBits sums Go's math.Log2, ported with its Frexp and its Log, so that the double is Go's, on the VM and on the web. wordkey.dart shares its check of each rune, checkWordRune, with the same behaviour. lib/datekeys.dart does not export the new file yet. test/vectors/wordlist_vectors.json, from tool/wordlist_go_vectors.go in an export of datekeys-go at 27a75ee, holds what Go gives: List on 19 texts, CheckList on 83 lists and on every code point of planes 0, 1 and 14, Generate in 51 cases, on the Spanish list and on lists of 12 to 2^20 + 1 words, from seeded, counter and finite streams, and Bits bit for bit. wordlist_test.dart runs them, also compiled to JavaScript, with the cases of TestCheckList, TestGenerate and TestBits of Go; wordlist_vm_test.dart checks the Dart copy of the vectors and every code point. The seed of TestGenerate of Go draws two indices only, 1793 and 2081, so that Generate runs out of bytes and the test compares two errors; the vectors record it. Co-Authored-By: Claude Opus 5.5 --- lib/src/wordkey.dart | 43 +- lib/src/wordlist.dart | 295 ++++++++++ test/vectors/wordlist_vectors.g.dart | 794 +++++++++++++++++++++++++++ test/vectors/wordlist_vectors.json | 787 ++++++++++++++++++++++++++ test/wordlist_support.dart | 168 ++++++ test/wordlist_test.dart | 341 ++++++++++++ test/wordlist_vm_test.dart | 53 ++ tool/wordlist_go_vectors.go | 727 ++++++++++++++++++++++++ 8 files changed, 3190 insertions(+), 18 deletions(-) create mode 100644 lib/src/wordlist.dart create mode 100644 test/vectors/wordlist_vectors.g.dart create mode 100644 test/vectors/wordlist_vectors.json create mode 100644 test/wordlist_support.dart create mode 100644 test/wordlist_test.dart create mode 100644 test/wordlist_vm_test.dart create mode 100644 tool/wordlist_go_vectors.go diff --git a/lib/src/wordkey.dart b/lib/src/wordkey.dart index dbe8755..ea31c3c 100644 --- a/lib/src/wordkey.dart +++ b/lib/src/wordkey.dart @@ -116,24 +116,7 @@ void checkWordsUtf8(List> words) { final b = w[i]; final (r, size) = b < 0x80 ? (b, 1) : decodeRune(w, i); i += size; - // Go's unicode.IsControl: C0 and C1, nothing above U+00FF. - if (r <= 0x1f || (r >= 0x7f && r <= 0x9f)) { - throw WordKeyException( - 'wordkey: the words hold the control character ${codePointName(r)}', - ); - } - if (isDefaultIgnorable(r)) { - throw WordKeyException( - 'wordkey: the words hold the invisible character ' - '${codePointName(r)}', - ); - } - if (!isAssigned(r)) { - throw WordKeyException( - 'wordkey: the words hold ${codePointName(r)}, unassigned in ' - 'Unicode $unicodeVersion', - ); - } + checkWordRune(r); } if (n >= minLetters) counted.add(String.fromCharCodes(w)); } @@ -145,6 +128,30 @@ void checkWordsUtf8(List> words) { } } +/// Throws the [WordKeyException] of Go's wordkey.checkRunes when the rune +/// [r] of a word is a control, a Default_Ignorable_Code_Point or a code +/// point unassigned in Unicode 18.0.0: the check of each rune of +/// [checkWords], and of each word of a list in wordlist.dart. +void checkWordRune(int r) { + // Go's unicode.IsControl: C0 and C1, nothing above U+00FF. + if (r <= 0x1f || (r >= 0x7f && r <= 0x9f)) { + throw WordKeyException( + 'wordkey: the words hold the control character ${codePointName(r)}', + ); + } + if (isDefaultIgnorable(r)) { + throw WordKeyException( + 'wordkey: the words hold the invisible character ${codePointName(r)}', + ); + } + if (!isAssigned(r)) { + throw WordKeyException( + 'wordkey: the words hold ${codePointName(r)}, unassigned in Unicode ' + '$unicodeVersion', + ); + } +} + /// The salt S of spec §38.1: `DateKeys llave de palabras v2|`, the chain /// hash in lower-case hexadecimal, `|`, the round in decimal, `|` and the /// capsule_id in lower-case hexadecimal, as Go's wordkey.Key writes it with diff --git a/lib/src/wordlist.dart b/lib/src/wordlist.dart new file mode 100644 index 0000000..4ac8ec7 --- /dev/null +++ b/lib/src/wordlist.dart @@ -0,0 +1,295 @@ +/// The random words of a key of words (spec §38.1: at least 6 words of a +/// public list of 2048 or more, which a writer SHOULD offer), as List, +/// CheckList, Generate and Bits of package wordkey of datekeys-go +/// (generate.go): the word lists of datekeys-go, taken only with the +/// SHA-256 pinned here and checked against the alphabet of their language; +/// the words drawn from one, uniformly, with a [RandomSource]; and their +/// strength in bits. +/// +/// Go builds its lists into the module; this library holds none. The app +/// downloads or bundles the file of a list, `wordkey/lists/.txt` of +/// datekeys-go (vendored in wordlists/ of this package), and gives its +/// bytes to [readWordList], which trusts none: their SHA-256 must be that of +/// [wordListSha256], and the words must pass [checkWordList]. The lists are +/// not normative: a reader does not need them, because the key is derived +/// from the normalized text of the words, whatever list they came from. +/// Each list has a license of its own, which its README records (es.txt is +/// CC BY-SA 4.0, an adaptation of FrequencyWords by Hermit Dave), unlike the +/// code. +/// +/// As in wordkey.dart, a Dart String is taken as its UTF-8 bytes +/// ([utf8Bytes]), and the functions ending in `Utf8` take the bytes of a Go +/// string: every input gives the result and the text of Go. +library; + +import 'dart:math' as math; +import 'dart:typed_data'; + +import 'bytes.dart'; +import 'pathrule.dart' show codePointName; +import 'random.dart'; +import 'sha256.dart'; +import 'wordkey.dart'; + +/// The number of words that [generateWords] draws when the caller does not +/// ask for more: 7 words of a list of 7776 are about 90 bits ([wordBits]). +const defaultWordCount = 7; + +/// The fewest words of a list that [checkWordList] accepts (spec §38.1: at +/// least 6 words of a list of 2048 or more). +const minListSize = 2048; + +/// The SHA-256 of each word list of datekeys-go, by language, as its +/// wordkey/lists/README.md records it: [readWordList] takes a list only with +/// these bytes, so that a list changes only with its hash here. +const Map wordListSha256 = { + 'es': 'ff77b487765c000da97cca58fe94a2cdb947303e7a07460614d7d95d800034fe', +}; + +// The letters that a word of a list of each language may hold, as the list +// writes it: lower case, in NFC. A word with a letter of another script that +// looks like one of these, such as the Cyrillic U+0430 for the Latin a, +// would be written down and typed again with the letter of the keyboard, and +// the capsule would not open. The alphabet of a list comes from here, never +// from the list: Go's alphabets. +const _alphabets = { + 'es': 'abcdefghijklmnopqrstuvwxyz\u00e1\u00e9\u00ed\u00f3\u00fa\u00fc\u00f1', +}; + +String _q(String s) => goQuote(utf8Bytes(s)); + +/// The languages of the lists of [wordListSha256], sorted: Go's Languages. +List wordListLanguages() => wordListSha256.keys.toList()..sort(); + +/// The words of [file], the word list of the language [lang], one word per +/// line, as Go's List gives the list built into it: [file] must have the +/// SHA-256 of [wordListSha256], and its words must pass [checkWordList]. +/// For a list that the app downloads or bundles, which it trusts no more +/// than any other download. Throws a [WordKeyException] with Go's text: +/// `wordkey: no word list for "xx"; the lists are es` for a language +/// without a list; `wordkey: the list "es" has the SHA-256 …, not …` for any +/// other bytes; and the error of [checkWordList] after `wordkey: the list +/// "es": `. +List readWordList(String lang, List file) { + final want = wordListSha256[lang]; + if (want == null) { + throw WordKeyException( + 'wordkey: no word list for ${_q(lang)}; the lists are ' + '${wordListLanguages().join(', ')}', + ); + } + final got = toHex(sha256(file)); + if (got != want) { + throw WordKeyException( + 'wordkey: the list ${_q(lang)} has the SHA-256 $got, not $want', + ); + } + return parseWordList(lang, file); +} + +/// [readWordList] without its two first checks, the language and the +/// SHA-256: the lines of [file], split as Go's List splits its text, +/// `strings.Split(strings.TrimSuffix(text, "\n"), "\n")`, and checked with +/// [checkWordListUtf8]. The bytes are taken as Go takes a string: a byte +/// that is not valid UTF-8 is U+FFFD, which no alphabet holds, so the check +/// refuses it with Go's text, and the words that pass are decoded strictly. +/// For the tests: the app reads a list with [readWordList]. +List parseWordList(String lang, List file) { + final lines = _lines(file); + try { + checkWordListUtf8(lang, lines); + } on WordKeyException catch (e) { + throw WordKeyException('wordkey: the list ${_q(lang)}: ${e.message}'); + } + return [for (final l in lines) decodeUtf8(l)!]; +} + +// The lines of [file], as Go's strings.Split(strings.TrimSuffix(text, +// "\n"), "\n"): one final LF goes, and the text is split at every LF, so +// that an empty text is one empty line. A byte 0x0A is never part of a +// longer UTF-8 sequence. +List _lines(List file) { + final b = file is Uint8List ? file : Uint8List.fromList(file); + final end = b.isNotEmpty && b.last == 0x0a ? b.length - 1 : b.length; + final lines = []; + var start = 0; + for (var i = 0; i < end; i++) { + if (b[i] == 0x0a) { + lines.add(Uint8List.sublistView(b, start, i)); + start = i + 1; + } + } + lines.add(Uint8List.sublistView(b, start, end)); + return lines; +} + +/// Checks that [words] can be a list of the language [lang] for +/// [generateWords], as Go's CheckList: the same checks, in the same order, +/// with Go's text in a [WordKeyException]. It refuses a language without an +/// alphabet here; fewer than [minListSize] words; a word that is not one +/// word of [minLetters] characters or more once normalized +/// ([normalizeWords]), that holds a character that [checkWords] refuses, or +/// one that is not a letter of the alphabet of [lang], as the list writes +/// it; and a word that is the same as an earlier one once normalized. Two +/// words such as «papa» and «papá» would be one word with less entropy than +/// the list promises. +void checkWordList(String lang, List words) => + checkWordListUtf8(lang, [for (final w in words) utf8Bytes(w)]); + +/// [checkWordList] of the bytes of [words]. +void checkWordListUtf8(String lang, List> words) { + final alphabet = _alphabets[lang]; + if (alphabet == null) { + throw WordKeyException('no alphabet for the language ${_q(lang)}'); + } + if (words.length < minListSize) { + throw WordKeyException('${words.length} words, fewer than $minListSize'); + } + final letters = alphabet.runes.toSet(); + // The first word of the list that is each normalized word. + final seen = >{}; + for (var i = 0; i < words.length; i++) { + final w = words[i]; + final line = i + 1; + final n = normalizeWordsUtf8(w); + // Go also refuses a word with white space at its ends, which a word of + // normalizeWords never has. + if (n.length != 1 || n[0].runes.length < minLetters) { + throw WordKeyException( + 'line $line, ${goQuote(w)}, is not one word of $minLetters or more ' + 'letters', + ); + } + try { + for (final r in n[0].runes) { + checkWordRune(r); + } + } on WordKeyException catch (e) { + throw WordKeyException('line $line: ${e.message}'); + } + // The runes of the word as the list writes it, as Go's `for range` + // reads them: a byte that is not valid UTF-8 is U+FFFD. + for (var j = 0; j < w.length;) { + final (r, size) = w[j] < 0x80 ? (w[j], 1) : decodeRune(w, j); + if (!letters.contains(r)) { + throw WordKeyException( + 'line $line, ${goQuote(w)}, holds ${codePointName(r)}, which is ' + 'not in the alphabet of ${_q(lang)}', + ); + } + j += size; + } + final prev = seen[n[0]]; + if (prev != null) { + throw WordKeyException( + 'line $line, ${goQuote(w)}, is the same word as ${goQuote(prev)} ' + 'once normalized', + ); + } + seen[n[0]] = w; + } +} + +/// [n] different words of [list], drawn uniformly with [random], the CSPRNG +/// of the platform by default, as Go's Generate: each index as +/// crypto/rand.Int draws it ([randomIndex]), and an index already drawn is +/// drawn again, so that the same random bytes draw the same words as Go. +/// Each word adds log2 of the size of the list, a little less for each word +/// already drawn ([wordBits]). The list is taken as it is: it is one that +/// [readWordList] gave. +/// +/// Throws a [WordKeyException] with Go's text when [n] is less than +/// [minWords] or more than half the list, before drawing anything. What +/// [random] throws goes through: a [RandomSource] does not run out, where +/// Go's io.Reader can, and Go's Generate then fails with `wordkey: EOF`. +List generateWords( + List list, [ + int n = defaultWordCount, + RandomSource random = secureRandom, +]) { + if (n < minWords) { + throw WordKeyException( + 'wordkey: a key of words needs at least $minWords words, not $n', + ); + } + if (n > list.length ~/ 2) { + throw WordKeyException('wordkey: $n words of a list of ${list.length}'); + } + final drawn = {}; + final words = []; + while (words.length < n) { + final i = randomIndex(random, list.length); + if (drawn.add(i)) words.add(list[i]); + } + return words; +} + +/// The strength of [count] words that [generateWords] draws from a list of +/// [size] words, as Go's Bits: log2 of the number of draws in order, +/// size·(size − 1)·…, which whoever knows the list must search, before the +/// rounds of PBKDF2. It is the sum of the log2 of size − i for each i below +/// [count], each by the math.Log2 of Go, so that the double is Go's, on the +/// VM and on the web: 7 words of 7776 are a little under 90.5 bits. +double wordBits(int size, int count) { + var b = 0.0; + for (var i = 0; i < count; i++) { + b += _log2((size - i).toDouble()); + } + return b; +} + +// Go's math.Log2 of [x], the one of every platform but s390x: x is +// frac·2^exp with frac in [0.5, 1), as math.Frexp splits it; a power of two +// gives exp − 1, exactly, and any other x Log(frac)·(1/Ln2) + exp. 0 gives +// −Infinity and a negative x NaN, as in Go. +double _log2(double x) { + if (x == 0) return double.negativeInfinity; + if (x < 0 || x.isNaN) return double.nan; + if (x.isInfinite) return x; + final (frac, exp) = _frexp(x); + if (frac == 0.5) return (exp - 1).toDouble(); + // dart:math's log2e is Go's 1/Ln2 as a float64, 0x3ff71547652b82fe. + return _log(frac) * math.log2e + exp; +} + +final _float = ByteData(8); + +// Go's math.Frexp of [x], positive and normal: frac in [0.5, 1) and exp, +// with x = frac·2^exp, from the bits of x. Only the high 32 bits change, so +// that the bit operators are exact on the web too. +(double, int) _frexp(double x) { + _float.setFloat64(0, x); + final high = _float.getUint32(0); + _float.setUint32(0, (high & 0x000fffff) | 0x3fe00000); + return (_float.getFloat64(0), (high >> 20) - 1022); +} + +// Go's math.Log of [x], positive and normal: its port of FreeBSD's +// e_log.c, with the operations of its code, and of its assembly for amd64, +// in their order, so that each double is Go's. +double _log(double x) { + const ln2Hi = 6.93147180369123816490e-01; // 3fe62e42 fee00000 + const ln2Lo = 1.90821492927058770002e-10; // 3dea39ef 35793c76 + const l1 = 6.666666666666735130e-01; // 3fe55555 55555593 + const l2 = 3.999999999940941908e-01; // 3fd99999 9997fa04 + const l3 = 2.857142874366239149e-01; // 3fd24924 94229359 + const l4 = 2.222219843214978396e-01; // 3fcc71c5 1d8e78af + const l5 = 1.818357216161805012e-01; // 3fc74664 96cb03de + const l6 = 1.531383769920937332e-01; // 3fc39a09 d078c69f + const l7 = 1.479819860511658591e-01; // 3fc2f112 df3e5244 + var (f1, ki) = _frexp(x); + if (f1 < math.sqrt2 / 2) { + f1 *= 2; + ki--; + } + final f = f1 - 1; + final k = ki.toDouble(); + final s = f / (2 + f); + final s2 = s * s; + final s4 = s2 * s2; + final t1 = s2 * (l1 + s4 * (l3 + s4 * (l5 + s4 * l7))); + final t2 = s4 * (l2 + s4 * (l4 + s4 * l6)); + final r = t1 + t2; + final hfsq = 0.5 * f * f; + return k * ln2Hi - ((hfsq - (s * (hfsq + r) + k * ln2Lo)) - f); +} diff --git a/test/vectors/wordlist_vectors.g.dart b/test/vectors/wordlist_vectors.g.dart new file mode 100644 index 0000000..0d16002 --- /dev/null +++ b/test/vectors/wordlist_vectors.g.dart @@ -0,0 +1,794 @@ +// Generated by tool/wordlist_go_vectors.go from wordlist_vectors.json, for +// the tests that also run compiled to JavaScript, where no file can be +// read. Do not edit. + +/// The text of test/vectors/wordlist_vectors.json. +const wordlistVectorsJson = r''' +{ + "description": "The word lists of package wordkey of the Go reference (generate.go, spec \u00a738.1) for lib/src/wordlist.dart; see tool/wordlist_go_vectors.go. Binary values and words are lower-case hex. The base list is word i = pal and three letters, a + i/676, a + i/26%26 and a + i%26; a case of size n takes its first n words, replaces the word at each at of set, and adds those of append. lists: the SHA-256, bytes and words of each built-in list. parse: the body of List on the text prefix, the base list joined by sep, and suffix (sha256 is that of the text): the words read, and ok or the error. check_list: CheckList, ok or the error (sha256 is that of the words joined by LF). alphabet: CheckList of the base list of 2048 whose first word is pala, a code point and zz, for each code point of the planes but the surrogates: the SHA-256 of the lines U+XXXX result, the code points of the words it accepts, and alphabet_results, each result up to U+017F. generate: Generate on the list of the Spanish words (list es) or on a list of size words whose indices they are, reading a stream: seeded, the keystream of SeededRandomSource of the seed; counter, SHA-256 of the label and a 32-bit big-endian counter from 0, block after block; bytes, hex repeated repeat times, which end. The indices drawn, the bytes read and the next four of an endless stream, or the error. bits: Bits, its shortest decimal and the hex of its float64. bits_digests: the SHA-256 of the 8 big-endian bytes of each Bits of the sizes and counts, inclusive, sizes outer.", + "generator": "tool/wordlist_go_vectors.go, go1.26.8", + "source": "27a75eefcd2ac2a3b32930d6872f3b5b6e648792", + "default_count": 7, + "min_list_size": 2048, + "min_words": 6, + "min_letters": 3, + "alphabet": {"word":"pala, the code point and zz, the first word of the base list of 2048","planes":[0,1,14],"count":194560,"sha256":"9119a1741586b087cc8fdcce99b00931d34c926f5dc54d7fa0ff250402a11ba9","ok":["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","\u00e1","\u00e9","\u00ed","\u00f1","\u00f3","\u00fa","\u00fc"]}, + "lists": [ + {"lang":"es","sha256":"ff77b487765c000da97cca58fe94a2cdb947303e7a07460614d7d95d800034fe","bytes":61843,"words":7776} + ], + "parse": [ + {"name":"2048 words, one per line, with a final LF","lang":"es","size":2048,"prefix":"","sep":"0a","suffix":"0a","sha256":"40e5649349cf1302065f2ceda7e7c4aec69e423fb8916c20b4445b229df6add1","words":2048,"result":"ok"}, + {"name":"without the final LF","lang":"es","size":2048,"prefix":"","sep":"0a","suffix":"","sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","words":2048,"result":"ok"}, + {"name":"7776 words","lang":"es","size":7776,"prefix":"","sep":"0a","suffix":"0a","sha256":"ed7549c5528253a352f8359ddb6cdcd7430536b97de1c42e2e2b20660e1db48c","words":7776,"result":"ok"}, + {"name":"an empty last line: two final LF","lang":"es","size":2048,"prefix":"","sep":"0a","suffix":"0a0a","sha256":"5299dfa91913c2444195faa2c595acd72ad3712d8a9c9b8d1f5cf54c48c175c0","words":0,"result":"wordkey: the list \"es\": line 2049, \"\", is not one word of 3 or more letters"}, + {"name":"an empty first line","lang":"es","size":2048,"prefix":"0a","sep":"0a","suffix":"0a","sha256":"3570e47619facf0aef02f91bb5c7ffb4836896e4793b22a34e6cb9a41e24a4f3","words":0,"result":"wordkey: the list \"es\": line 1, \"\", is not one word of 3 or more letters"}, + {"name":"CR LF lines","lang":"es","size":2048,"prefix":"","sep":"0d0a","suffix":"0d0a","sha256":"5101863512608d6f32553f12c84f0a12e1b211bf5ab2b97e80d62a75b3d104f4","words":0,"result":"wordkey: the list \"es\": line 1, \"palaaa\\r\", holds U+000D, which is not in the alphabet of \"es\""}, + {"name":"CR LF lines, the last without","lang":"es","size":2048,"prefix":"","sep":"0d0a","suffix":"","sha256":"2b7926ee88319902d851db25b98b86f322317cb831b006659bc2b813683e0332","words":0,"result":"wordkey: the list \"es\": line 1, \"palaaa\\r\", holds U+000D, which is not in the alphabet of \"es\""}, + {"name":"CR lines","lang":"es","size":2048,"prefix":"","sep":"0d","suffix":"0d","sha256":"475eae5815dc03f07b0ebb538ac7dcb04b87a10e589f6a9aec4355b896ccf92a","words":0,"result":"wordkey: the list \"es\": 1 words, fewer than 2048"}, + {"name":"a byte order mark","lang":"es","size":2048,"prefix":"efbbbf","sep":"0a","suffix":"0a","sha256":"984ec86238f6eff77e6426203cfddda9068720fc8e1db26c36f9070efce4dbbe","words":0,"result":"wordkey: the list \"es\": line 1: wordkey: the words hold the invisible character U+FEFF"}, + {"name":"an empty text","lang":"es","size":0,"prefix":"","sep":"0a","suffix":"","sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","words":0,"result":"wordkey: the list \"es\": 1 words, fewer than 2048"}, + {"name":"an LF only","lang":"es","size":0,"prefix":"","sep":"0a","suffix":"0a","sha256":"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b","words":0,"result":"wordkey: the list \"es\": 1 words, fewer than 2048"}, + {"name":"2047 words","lang":"es","size":2047,"prefix":"","sep":"0a","suffix":"0a","sha256":"6254d217042f509c1c5d32a4ad3d907b45105a167e75b41b6b5e088ff304fc1e","words":0,"result":"wordkey: the list \"es\": 2047 words, fewer than 2048"}, + {"name":"the words separated by spaces","lang":"es","size":2048,"prefix":"","sep":"20","suffix":"0a","sha256":"10dae8e91c4d951d43dafc1c2a37d32041bf1d1909a15ff9b0bd15244214f4c3","words":0,"result":"wordkey: the list \"es\": 1 words, fewer than 2048"}, + {"name":"a language without an alphabet","lang":"xx","size":2048,"prefix":"","sep":"0a","suffix":"0a","sha256":"40e5649349cf1302065f2ceda7e7c4aec69e423fb8916c20b4445b229df6add1","words":0,"result":"wordkey: the list \"xx\": no alphabet for the language \"xx\""}, + {"name":"a byte that is not valid UTF-8","lang":"es","size":2048,"set":[{"at":6,"word":"70616cff6161"}],"prefix":"","sep":"0a","suffix":"0a","sha256":"31c967816ac079ef582ad79fe4ce76df580e02dade6b6bf1f4e865e7ed333a11","words":0,"result":"wordkey: the list \"es\": line 7, \"pal\\xffaa\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"a sequence cut at the end of the text","lang":"es","size":2048,"set":[{"at":2047,"word":"70616c7a7ac3"}],"prefix":"","sep":"0a","suffix":"","sha256":"2e6660234b4afb4d3a02660f71b8c8b80b7d245d9d5324730a7ba5af90a2064b","words":0,"result":"wordkey: the list \"es\": line 2048, \"palzz\\xc3\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"the same word twice","lang":"es","size":2048,"set":[{"at":2000,"word":"70616c616161"}],"prefix":"","sep":"0a","suffix":"0a","sha256":"9f2acbb0eae1bb8003be8a8721e54a0905d2f776e8c4a2d467a920c4e3141922","words":0,"result":"wordkey: the list \"es\": line 2001, \"palaaa\", is the same word as \"palaaa\" once normalized"}, + {"name":"a capital letter","lang":"es","size":2048,"set":[{"at":100,"word":"50616c647777"}],"prefix":"","sep":"0a","suffix":"0a","sha256":"c145284ea3e147b5527ceb511740a980af3cb53289176da82e08d084d741833d","words":0,"result":"wordkey: the list \"es\": line 101, \"Paldww\", holds U+0050, which is not in the alphabet of \"es\""}, + {"name":"letters of the alphabet","lang":"es","size":2048,"set":[{"at":0,"word":"c3a1c3a9c3adc3b3c3bac3bcc3b1"}],"prefix":"","sep":"0a","suffix":"0a","sha256":"62b5e70acd207e5609c415f64652174b4f29418f39daf4d9a83a89a3aa778e20","words":2048,"result":"ok"} + ], + "check_list": [ + {"name":"the base list","lang":"es","size":2048,"sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","result":"ok"}, + {"name":"a language without an alphabet","lang":"xx","size":2048,"sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","result":"no alphabet for the language \"xx\""}, + {"name":"2047 words","lang":"es","size":2047,"sha256":"006232a478c66e976927c8614ebea20ea657baf0ae52f80ec53c81d57a419957","result":"2047 words, fewer than 2048"}, + {"name":"two words in a line","lang":"es","size":2048,"set":[{"at":5,"word":"646f732070616c6162726173"}],"sha256":"f42912452330cc6b7471acab57b52d26d6d05f81afd5dbea729f579beedeb3de","result":"line 6, \"dos palabras\", is not one word of 3 or more letters"}, + {"name":"two spaces","lang":"es","size":2048,"set":[{"at":5,"word":"2020"}],"sha256":"cc58b1f63c0f95a24c8a9e7c1159ee8f1372243227a09d389f5bb77034fd8088","result":"line 6, \" \", is not one word of 3 or more letters"}, + {"name":"two letters","lang":"es","size":2048,"set":[{"at":5,"word":"6d69"}],"sha256":"9295042e20f0a44e0c567c74aee7c1431406698d0876deaf6c6a9d221dacbe06","result":"line 6, \"mi\", is not one word of 3 or more letters"}, + {"name":"ZWSP","lang":"es","size":2048,"set":[{"at":5,"word":"63617361e2808b"}],"sha256":"e2047d1479f8a0c1bcdc7c432cd51f84b44164fdb6fc550aacd4b67eae868cc7","result":"line 6: wordkey: the words hold the invisible character U+200B"}, + {"name":"a capital","lang":"es","size":2048,"set":[{"at":5,"word":"50616c616166"}],"sha256":"ab2d74b6b1aa4ebc6154e932f1db82e8cbe9eaa8a95c3362c3f77cb577323e95","result":"line 6, \"Palaaf\", holds U+0050, which is not in the alphabet of \"es\""}, + {"name":"a Cyrillic letter that looks like a Latin c","lang":"es","size":2048,"set":[{"at":5,"word":"d181617361"}],"sha256":"0a2eebb54d9a57dad50b557a06eb73fd0bbeb468a5c8bb72705d4c62db11ee38","result":"line 6, \"\u0441asa\", holds U+0441, which is not in the alphabet of \"es\""}, + {"name":"a digit","lang":"es","size":2048,"set":[{"at":5,"word":"70616c31"}],"sha256":"e125536a8e6d771fb734db57ae5cf630583558af2957f0ed42e3b9a50aba7a43","result":"line 6, \"pal1\", holds U+0031, which is not in the alphabet of \"es\""}, + {"name":"the CR of a CR LF line","lang":"es","size":2048,"set":[{"at":5,"word":"70616c6161660d"}],"sha256":"bfbabbff5776d427b31f38898a61d52c0396bc1609baf8ee31828698d35b7e00","result":"line 6, \"palaaf\\r\", holds U+000D, which is not in the alphabet of \"es\""}, + {"name":"the same word","lang":"es","size":2048,"set":[{"at":5,"word":"70616c616165"}],"sha256":"1993a45d3423b863588c5211ca64859d9568fd433cac83d93e3fa6383ada8d55","result":"line 6, \"palaae\", is the same word as \"palaae\" once normalized"}, + {"name":"the same word once normalized","lang":"es","size":2048,"set":[{"at":5,"word":"70616c61c3a165"}],"sha256":"e2abb6dda7cc7f1e7eeb62d25c9e4e910b48265b17643db34a83f82b10b8bd12","result":"line 6, \"pala\u00e1e\", is the same word as \"palaae\" once normalized"}, + {"name":"papa after pap\u00e1","lang":"es","size":2048,"set":[{"at":0,"word":"706170c3a1"}],"append":["70617061"],"sha256":"8feff334849c99f57f0730a53d0b69193d319cc5311ed35fd7c63c1ccd822108","result":"line 2049, \"papa\", is the same word as \"pap\u00e1\" once normalized"}, + {"name":"no words","lang":"es","size":0,"sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","result":"0 words, fewer than 2048"}, + {"name":"no words in a language without an alphabet","lang":"xx","size":0,"sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","result":"no alphabet for the language \"xx\""}, + {"name":"the empty language","lang":"","size":2048,"sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","result":"no alphabet for the language \"\""}, + {"name":"ES, in capitals","lang":"ES","size":2048,"sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","result":"no alphabet for the language \"ES\""}, + {"name":"es and a space","lang":"es ","size":2048,"sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","result":"no alphabet for the language \"es \""}, + {"name":"espa\u00f1ol","lang":"espa\u00f1ol","size":2048,"sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","result":"no alphabet for the language \"espa\u00f1ol\""}, + {"name":"2049 words","lang":"es","size":2049,"sha256":"4a3d02931aa351dbabd89a53ec77ae4008f2e7b1021ff4b3b8d62af0c2f5d486","result":"ok"}, + {"name":"7776 words","lang":"es","size":7776,"sha256":"d143891cbb69ea644de7f2036b93e6fd99040b7bee852aee3a9f21b8147b5fe2","result":"ok"}, + {"name":"17576 words","lang":"es","size":17576,"sha256":"88120b465c3f3fdf5d987f982de3ca66a56225595af185bd242a857843c74777","result":"ok"}, + {"name":"an empty word","lang":"es","size":2048,"set":[{"at":5,"word":""}],"sha256":"639e41bb771d1c353a573e01d40dd1bfb985f01563cf3ff572826ef258f14c50","result":"line 6, \"\", is not one word of 3 or more letters"}, + {"name":"a word of three letters","lang":"es","size":2048,"set":[{"at":5,"word":"70616c"}],"sha256":"78956c5afcfb1abb4844700cb7aae4168b65e7c841177446758e44b44df380dd","result":"ok"}, + {"name":"\u00f1u, two letters","lang":"es","size":2048,"set":[{"at":5,"word":"c3b175"}],"sha256":"8cc44a85f48c935cfb342d979d758e66404d64c56a38387f8b5ecfb07ba4dcaf","result":"line 6, \"\u00f1u\", is not one word of 3 or more letters"}, + {"name":"\u00f1u\u00f1, three letters","lang":"es","size":2048,"set":[{"at":5,"word":"c3b175c3b1"}],"sha256":"dc2601fdba7c90d378652295611a41a84611c895bb14e0d0cdc2164fdf037972","result":"ok"}, + {"name":"a space before","lang":"es","size":2048,"set":[{"at":5,"word":"2070616c616166"}],"sha256":"382f4bf269831d42e0ce019b63551fe99c0290419dcc7a56002a1c2c0f0b587a","result":"line 6, \" palaaf\", holds U+0020, which is not in the alphabet of \"es\""}, + {"name":"a space after","lang":"es","size":2048,"set":[{"at":5,"word":"70616c61616620"}],"sha256":"b538a1983df04e91d58774665aefc9b3ab22a1122c2a0cd380d93c1ebe1a7af5","result":"line 6, \"palaaf \", holds U+0020, which is not in the alphabet of \"es\""}, + {"name":"a tab inside","lang":"es","size":2048,"set":[{"at":5,"word":"70616c096166"}],"sha256":"0bbf370209dd5189292c89a5c0c337a6059affcf8771706b0ab1aef66e30cb6a","result":"line 6, \"pal\\taf\", is not one word of 3 or more letters"}, + {"name":"NBSP inside","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc2a06166"}],"sha256":"09cc345e8cedaeb60f7021c558100348ae482219f4184f7672661bb7872c21e5","result":"line 6, \"pal\\u00a0af\", is not one word of 3 or more letters"}, + {"name":"NEL inside","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc2856166"}],"sha256":"066ac85c3b4af72f1d3976b29c5809d0a4182d7dc3ba1c09eef2ebaedf1f9ebd","result":"line 6, \"pal\\u0085af\", is not one word of 3 or more letters"}, + {"name":"the ideographic space inside","lang":"es","size":2048,"set":[{"at":5,"word":"70616ce380806166"}],"sha256":"36bd83e640c63002bccfac2b6b34ce4f4bec6d0e92bbddeca871adf0c3e6172d","result":"line 6, \"pal\\u3000af\", is not one word of 3 or more letters"}, + {"name":"LS inside","lang":"es","size":2048,"set":[{"at":5,"word":"70616ce280a86166"}],"sha256":"b545bea83ab3d4b7dcaaa8e5b77cec190f8bf4273a0b38884225f332bfc2972d","result":"line 6, \"pal\\u2028af\", is not one word of 3 or more letters"}, + {"name":"an LF inside","lang":"es","size":2048,"set":[{"at":5,"word":"70616c0a6166"}],"sha256":"c48562076662e79dbd764e23894898f217a1f1f97f1abb2e9299ba7ac420afed","result":"line 6, \"pal\\naf\", is not one word of 3 or more letters"}, + {"name":"two runes and ZWSP: the count before the runes","lang":"es","size":2048,"set":[{"at":5,"word":"70e2808b"}],"sha256":"3e03fc5d9a4c0ac2c2e777da46e79cc19f9b9df80b34aa1457ede9fa5d1c7788","result":"line 6, \"p\\u200b\", is not one word of 3 or more letters"}, + {"name":"three letters with a mark that goes: two","lang":"es","size":2048,"set":[{"at":5,"word":"7061cc81"}],"sha256":"4338fbbae7ca23244246854fbe205ce59fb5871bbdd9cf0a2410e3db4c8f5c5d","result":"line 6, \"pa\u0301\", is not one word of 3 or more letters"}, + {"name":"a\u0301b, two letters once normalized","lang":"es","size":2048,"set":[{"at":5,"word":"61cc8162"}],"sha256":"b302b105aa962d188c2a193a6e42138aac9a7748df2be22327e119b21fdb6868","result":"line 6, \"a\u0301b\", is not one word of 3 or more letters"}, + {"name":"a control","lang":"es","size":2048,"set":[{"at":5,"word":"70616c016166"}],"sha256":"6288c09787e3af1bb5058c78bd33f441f4c8835bd59f276b16233c62300304ea","result":"line 6: wordkey: the words hold the control character U+0001"}, + {"name":"DEL","lang":"es","size":2048,"set":[{"at":5,"word":"70616c7f6166"}],"sha256":"30f93486be369882aedc5198f463e57331b4d7297af5f18afbf3895280437850","result":"line 6: wordkey: the words hold the control character U+007F"}, + {"name":"a C1 control","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc2806166"}],"sha256":"f015c53765dede22e047bd2402a945e9c56227b5889bcc226da11ff4ab1b5059","result":"line 6: wordkey: the words hold the control character U+0080"}, + {"name":"a control and a capital: the runes before the alphabet","lang":"es","size":2048,"set":[{"at":5,"word":"50616c016166"}],"sha256":"8195b293f594de3c0e5b556f54a2a87cf02266b26f74ba76f4c0aaf2ef5b3b8f","result":"line 6: wordkey: the words hold the control character U+0001"}, + {"name":"a soft hyphen","lang":"es","size":2048,"set":[{"at":5,"word":"7061c2ad"}],"sha256":"b87ae826ab91465b27cd82974898617afc29f293253546aec71fb7f1a598f949","result":"line 6: wordkey: the words hold the invisible character U+00AD"}, + {"name":"ZWJ","lang":"es","size":2048,"set":[{"at":5,"word":"70616ce2808d6166"}],"sha256":"2859e13c093ce340b7c2f937bc4470f36680100cd7fba471e7eb13d6f50c5e84","result":"line 6: wordkey: the words hold the invisible character U+200D"}, + {"name":"a byte order mark","lang":"es","size":2048,"set":[{"at":5,"word":"efbbbf70616c616166"}],"sha256":"3c9cef5930c2d943eee1019ad595c2a723b15a8aef3e2aa6134c2fc24d28db76","result":"line 6: wordkey: the words hold the invisible character U+FEFF"}, + {"name":"an unassigned code point","lang":"es","size":2048,"set":[{"at":5,"word":"70616ccdb8"}],"sha256":"8bbd2df9847132be8c2e1aefecd699fb6100a242cc550bf89af79f23125bf925","result":"line 6: wordkey: the words hold U+0378, unassigned in Unicode 18.0.0"}, + {"name":"a noncharacter","lang":"es","size":2048,"set":[{"at":5,"word":"70616cefbfbe"}],"sha256":"e5b2f98df9529f872db3a5c46d57b9275d0f47128fc5d80279ebccec05770220","result":"line 6: wordkey: the words hold U+FFFE, unassigned in Unicode 18.0.0"}, + {"name":"a tag","lang":"es","size":2048,"set":[{"at":5,"word":"70616cf3a081816166"}],"sha256":"2ce05d430f2683ae4add6f38a3009b9af978608094c0de404366add14dbccb6d","result":"line 6: wordkey: the words hold the invisible character U+E0041"}, + {"name":"the letters of the alphabet","lang":"es","size":2048,"set":[{"at":5,"word":"6162636465666768696a6b6c6d6e6f707172737475767778797ac3a1c3a9c3adc3b3c3bac3bcc3b1"}],"sha256":"171612e5b64aca979e9f98d04c632252f41dd2c8b419d30b919a664ded7523c5","result":"ok"}, + {"name":"an acute accent in NFD","lang":"es","size":2048,"set":[{"at":5,"word":"70616c61cc8165"}],"sha256":"18d9d3d9837a8ab1d6236bf70454102e4cd62d78858ecaf5429a3bf5012ac681","result":"line 6, \"pala\u0301e\", holds U+0301, which is not in the alphabet of \"es\""}, + {"name":"a diaeresis in NFD","lang":"es","size":2048,"set":[{"at":5,"word":"70616c6161cc88"}],"sha256":"687b6e86c51a3298a4ce78742495d25302cc11228576f83bba7788188c7086d3","result":"line 6, \"palaa\u0308\", holds U+0308, which is not in the alphabet of \"es\""}, + {"name":"a tilde in NFD","lang":"es","size":2048,"set":[{"at":5,"word":"70616ecc836f"}],"sha256":"88e23891893b369e4cf68becc9cfe9fd84444c5002e353f87a684cd6a564d2c4","result":"line 6, \"pan\u0303o\", holds U+0303, which is not in the alphabet of \"es\""}, + {"name":"\u00c1, a capital with an accent","lang":"es","size":2048,"set":[{"at":5,"word":"c3816261636f"}],"sha256":"fc9405a1716bc62e7b194732c3a9bbc7c42ded47d7c169c2579d25290522e9bf","result":"line 6, \"\u00c1baco\", holds U+00C1, which is not in the alphabet of \"es\""}, + {"name":"\u00d1, a capital","lang":"es","size":2048,"set":[{"at":5,"word":"c391616e64c3ba"}],"sha256":"d48bed60f8744c2fc3f0f34a5e3f4e867e734f5fb7cbef82af6086e710b88d3c","result":"line 6, \"\u00d1and\u00fa\", holds U+00D1, which is not in the alphabet of \"es\""}, + {"name":"a grave accent","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc3a061"}],"sha256":"52748dc437c58a824f554dc2f870a5f49db3833e2a34023324d407e7b80cc658","result":"line 6, \"pal\u00e0a\", holds U+00E0, which is not in the alphabet of \"es\""}, + {"name":"a circumflex","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc3a261"}],"sha256":"e190dd09884acccb334e299438fc7eae1a8bd1d982a8197eac610977c9c14ef9","result":"line 6, \"pal\u00e2a\", holds U+00E2, which is not in the alphabet of \"es\""}, + {"name":"\u00e4","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc3a461"}],"sha256":"76c4d1e2b9821df83c705e792119b514c666877449ff97373aa83fb5eb3c6505","result":"line 6, \"pal\u00e4a\", holds U+00E4, which is not in the alphabet of \"es\""}, + {"name":"\u00e7","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc3a761"}],"sha256":"8bf7d649fd58ab3c1a5a432a162c43f174e56e0188a3c599025f5cdbf3df2e1a","result":"line 6, \"pal\u00e7a\", holds U+00E7, which is not in the alphabet of \"es\""}, + {"name":"\u00f6","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc3b661"}],"sha256":"590bcda940c5ae0f8f30c1f6d1b941ac0707e933f4af993c1072970cde920170","result":"line 6, \"pal\u00f6a\", holds U+00F6, which is not in the alphabet of \"es\""}, + {"name":"\u00fd","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc3bd61"}],"sha256":"72af7d5747ee97e630664d5fb5efd0f51c863d55e7424b7ee9ecac8aa1076b9b","result":"line 6, \"pal\u00fda\", holds U+00FD, which is not in the alphabet of \"es\""}, + {"name":"\u00df","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc39f61"}],"sha256":"d73bd84a27377847b8e0a039490c0924cd6e8dec83547f0913151bcd2a292d0c","result":"line 6, \"pal\u00dfa\", holds U+00DF, which is not in the alphabet of \"es\""}, + {"name":"a Cyrillic a","lang":"es","size":2048,"set":[{"at":5,"word":"70616cd0b061"}],"sha256":"9f1959893c6bbf097866272a1eb73a30b29356f6db232d10e48ea706ad95da94","result":"line 6, \"pal\u0430a\", holds U+0430, which is not in the alphabet of \"es\""}, + {"name":"a Greek omicron","lang":"es","size":2048,"set":[{"at":5,"word":"70616ccebf61"}],"sha256":"51591f2a3d611a835b14977093687b0fb0b82264aea304e847ec4e9a92e60721","result":"line 6, \"pal\u03bfa\", holds U+03BF, which is not in the alphabet of \"es\""}, + {"name":"a full-width a","lang":"es","size":2048,"set":[{"at":5,"word":"70616cefbd8161"}],"sha256":"466a6f43f3775f8009531c7200ab2d2cb01770da643e39e208b503a6adc8817e","result":"line 6, \"pal\uff41a\", holds U+FF41, which is not in the alphabet of \"es\""}, + {"name":"a mathematical bold a","lang":"es","size":2048,"set":[{"at":5,"word":"70616cf09d909a61"}],"sha256":"9cdb9150c16635f18c1edeb4a99be2b972dbe3534b96bc45518cb2be7c45d3c1","result":"line 6, \"pal\ud835\udc1aa\", holds U+1D41A, which is not in the alphabet of \"es\""}, + {"name":"the Kelvin sign","lang":"es","size":2048,"set":[{"at":5,"word":"70616ce284aa61"}],"sha256":"8296c53f65135f54af51349dda6315556aa5ab7c476bf09faafbbb3579567491","result":"line 6, \"pal\u212aa\", holds U+212A, which is not in the alphabet of \"es\""}, + {"name":"a dotless i","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc4b161"}],"sha256":"acff79df5e69176c3bd51aa70d8a0f20de8593c97cdc8d3f32c450cf30fb587a","result":"line 6, \"pal\u0131a\", holds U+0131, which is not in the alphabet of \"es\""}, + {"name":"a hyphen","lang":"es","size":2048,"set":[{"at":5,"word":"70616c2d6166"}],"sha256":"5b316070132e5fe53051a1cc61aba7ec9c324a6b11e23ce9e062823e8765af24","result":"line 6, \"pal-af\", holds U+002D, which is not in the alphabet of \"es\""}, + {"name":"an apostrophe","lang":"es","size":2048,"set":[{"at":5,"word":"70616c276166"}],"sha256":"a2fcd25525cf45943776c7b07471982a531c997227c3757d2fa375611d666d19","result":"line 6, \"pal'af\", holds U+0027, which is not in the alphabet of \"es\""}, + {"name":"a backtick and a brace, around a to z","lang":"es","size":2048,"set":[{"at":5,"word":"70616c607b"}],"sha256":"a1bf9fc3215154c3b002a53a4bcaeca5a30c21b7108dbfd23fc762e0da7d1e99","result":"line 6, \"pal`{\", holds U+0060, which is not in the alphabet of \"es\""}, + {"name":"an emoji","lang":"es","size":2048,"set":[{"at":5,"word":"70616cf09f9880"}],"sha256":"9a8aacbd11b71319a98472e41974ab3b78b4a8781ae33fa170220f4f5f2f84bc","result":"line 6, \"pal\ud83d\ude00\", holds U+1F600, which is not in the alphabet of \"es\""}, + {"name":"a byte that is not valid UTF-8","lang":"es","size":2048,"set":[{"at":5,"word":"70616cff6161"}],"sha256":"028e9203eda7205fb204a2bed86bb9126c70f80d3fcf2ccc59544d5a09a3dd45","result":"line 6, \"pal\\xffaa\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"a surrogate in UTF-8 bytes","lang":"es","size":2048,"set":[{"at":5,"word":"eda080616161"}],"sha256":"c175fc03314b4ac1a469dc46ab6888e6e0b62facd72f485e7369569a809e2ee0","result":"line 6, \"\\xed\\xa0\\x80aaa\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"a sequence cut short","lang":"es","size":2048,"set":[{"at":5,"word":"70616c61c3"}],"sha256":"b982ef907d87e08d79e038d579bbe0988a8c7eb190b83de73593168ea992ac4f","result":"line 6, \"pala\\xc3\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"an overlong NUL","lang":"es","size":2048,"set":[{"at":5,"word":"c080616161"}],"sha256":"536087a6fecd4b3a8ba068f8ab988149cb22ea63f09fa6878693cff47abed313","result":"line 6, \"\\xc0\\x80aaa\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"U+FFFD itself","lang":"es","size":2048,"set":[{"at":5,"word":"70616cefbfbd6161"}],"sha256":"a59f04e2deb66cb73a0487f13cf8d9255e3fb1594475ffd82ac424406ae686e7","result":"line 6, \"pal\ufffdaa\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"a\u00f1o and ano","lang":"es","size":2048,"set":[{"at":5,"word":"61c3b16f"},{"at":6,"word":"616e6f"}],"sha256":"8d616f5737a177219aa2531b9751d2e2ab0ccd7828f8c119d6cbca48fe17bf66","result":"line 7, \"ano\", is the same word as \"a\u00f1o\" once normalized"}, + {"name":"ping\u00fcino and pinguino","lang":"es","size":2048,"set":[{"at":5,"word":"70696e6775696e6f"},{"at":9,"word":"70696e67c3bc696e6f"}],"sha256":"ea28b2e6cef6fda1e67bb96638c93fe6634bd4cc5ce2dde4f0331aea64d130f6","result":"line 10, \"ping\u00fcino\", is the same word as \"pinguino\" once normalized"}, + {"name":"the same word, the first of the list last","lang":"es","size":2048,"append":["70616c616161"],"sha256":"24692d3331d9c5e2d9aeca9de2a6a89fbd941ac3237f68d901a291e1dfe52fa7","result":"line 2049, \"palaaa\", is the same word as \"palaaa\" once normalized"}, + {"name":"a capital of a word of the list: the alphabet before the same word","lang":"es","size":2048,"set":[{"at":5,"word":"50414c414145"}],"sha256":"bf4af0c60850edee7eb20f7e575d4b14fa16a193bc93a1333d4e502baea53df3","result":"line 6, \"PALAAE\", holds U+0050, which is not in the alphabet of \"es\""}, + {"name":"an error at line 4 and another at line 6","lang":"es","size":2048,"set":[{"at":3,"word":"4d616c"},{"at":5,"word":"7061"}],"sha256":"61e1d0c145b794b21f87db1a07f5bec75a104e9a03e0e64f8eb42dd584ccadf9","result":"line 4, \"Mal\", holds U+004D, which is not in the alphabet of \"es\""}, + {"name":"an error at the last line","lang":"es","size":2048,"set":[{"at":2047,"word":"78"}],"sha256":"9ccabe185e9b3a34151eaaa0c0a6d6d39488c5fac1ea9e72c898bf8ae43917a0","result":"line 2048, \"x\", is not one word of 3 or more letters"}, + {"name":"an empty last line","lang":"es","size":2048,"append":[""],"sha256":"40e5649349cf1302065f2ceda7e7c4aec69e423fb8916c20b4445b229df6add1","result":"line 2049, \"\", is not one word of 3 or more letters"} + ], + "alphabet_results": [ + {"rune":0,"result":"line 1: wordkey: the words hold the control character U+0000"}, + {"rune":1,"result":"line 1: wordkey: the words hold the control character U+0001"}, + {"rune":2,"result":"line 1: wordkey: the words hold the control character U+0002"}, + {"rune":3,"result":"line 1: wordkey: the words hold the control character U+0003"}, + {"rune":4,"result":"line 1: wordkey: the words hold the control character U+0004"}, + {"rune":5,"result":"line 1: wordkey: the words hold the control character U+0005"}, + {"rune":6,"result":"line 1: wordkey: the words hold the control character U+0006"}, + {"rune":7,"result":"line 1: wordkey: the words hold the control character U+0007"}, + {"rune":8,"result":"line 1: wordkey: the words hold the control character U+0008"}, + {"rune":9,"result":"line 1, \"pala\\tzz\", is not one word of 3 or more letters"}, + {"rune":10,"result":"line 1, \"pala\\nzz\", is not one word of 3 or more letters"}, + {"rune":11,"result":"line 1, \"pala\\vzz\", is not one word of 3 or more letters"}, + {"rune":12,"result":"line 1, \"pala\\fzz\", is not one word of 3 or more letters"}, + {"rune":13,"result":"line 1, \"pala\\rzz\", is not one word of 3 or more letters"}, + {"rune":14,"result":"line 1: wordkey: the words hold the control character U+000E"}, + {"rune":15,"result":"line 1: wordkey: the words hold the control character U+000F"}, + {"rune":16,"result":"line 1: wordkey: the words hold the control character U+0010"}, + {"rune":17,"result":"line 1: wordkey: the words hold the control character U+0011"}, + {"rune":18,"result":"line 1: wordkey: the words hold the control character U+0012"}, + {"rune":19,"result":"line 1: wordkey: the words hold the control character U+0013"}, + {"rune":20,"result":"line 1: wordkey: the words hold the control character U+0014"}, + {"rune":21,"result":"line 1: wordkey: the words hold the control character U+0015"}, + {"rune":22,"result":"line 1: wordkey: the words hold the control character U+0016"}, + {"rune":23,"result":"line 1: wordkey: the words hold the control character U+0017"}, + {"rune":24,"result":"line 1: wordkey: the words hold the control character U+0018"}, + {"rune":25,"result":"line 1: wordkey: the words hold the control character U+0019"}, + {"rune":26,"result":"line 1: wordkey: the words hold the control character U+001A"}, + {"rune":27,"result":"line 1: wordkey: the words hold the control character U+001B"}, + {"rune":28,"result":"line 1: wordkey: the words hold the control character U+001C"}, + {"rune":29,"result":"line 1: wordkey: the words hold the control character U+001D"}, + {"rune":30,"result":"line 1: wordkey: the words hold the control character U+001E"}, + {"rune":31,"result":"line 1: wordkey: the words hold the control character U+001F"}, + {"rune":32,"result":"line 1, \"pala zz\", is not one word of 3 or more letters"}, + {"rune":33,"result":"line 1, \"pala!zz\", holds U+0021, which is not in the alphabet of \"es\""}, + {"rune":34,"result":"line 1, \"pala\\\"zz\", holds U+0022, which is not in the alphabet of \"es\""}, + {"rune":35,"result":"line 1, \"pala#zz\", holds U+0023, which is not in the alphabet of \"es\""}, + {"rune":36,"result":"line 1, \"pala$zz\", holds U+0024, which is not in the alphabet of \"es\""}, + {"rune":37,"result":"line 1, \"pala%zz\", holds U+0025, which is not in the alphabet of \"es\""}, + {"rune":38,"result":"line 1, \"pala&zz\", holds U+0026, which is not in the alphabet of \"es\""}, + {"rune":39,"result":"line 1, \"pala'zz\", holds U+0027, which is not in the alphabet of \"es\""}, + {"rune":40,"result":"line 1, \"pala(zz\", holds U+0028, which is not in the alphabet of \"es\""}, + {"rune":41,"result":"line 1, \"pala)zz\", holds U+0029, which is not in the alphabet of \"es\""}, + {"rune":42,"result":"line 1, \"pala*zz\", holds U+002A, which is not in the alphabet of \"es\""}, + {"rune":43,"result":"line 1, \"pala+zz\", holds U+002B, which is not in the alphabet of \"es\""}, + {"rune":44,"result":"line 1, \"pala,zz\", holds U+002C, which is not in the alphabet of \"es\""}, + {"rune":45,"result":"line 1, \"pala-zz\", holds U+002D, which is not in the alphabet of \"es\""}, + {"rune":46,"result":"line 1, \"pala.zz\", holds U+002E, which is not in the alphabet of \"es\""}, + {"rune":47,"result":"line 1, \"pala/zz\", holds U+002F, which is not in the alphabet of \"es\""}, + {"rune":48,"result":"line 1, \"pala0zz\", holds U+0030, which is not in the alphabet of \"es\""}, + {"rune":49,"result":"line 1, \"pala1zz\", holds U+0031, which is not in the alphabet of \"es\""}, + {"rune":50,"result":"line 1, \"pala2zz\", holds U+0032, which is not in the alphabet of \"es\""}, + {"rune":51,"result":"line 1, \"pala3zz\", holds U+0033, which is not in the alphabet of \"es\""}, + {"rune":52,"result":"line 1, \"pala4zz\", holds U+0034, which is not in the alphabet of \"es\""}, + {"rune":53,"result":"line 1, \"pala5zz\", holds U+0035, which is not in the alphabet of \"es\""}, + {"rune":54,"result":"line 1, \"pala6zz\", holds U+0036, which is not in the alphabet of \"es\""}, + {"rune":55,"result":"line 1, \"pala7zz\", holds U+0037, which is not in the alphabet of \"es\""}, + {"rune":56,"result":"line 1, \"pala8zz\", holds U+0038, which is not in the alphabet of \"es\""}, + {"rune":57,"result":"line 1, \"pala9zz\", holds U+0039, which is not in the alphabet of \"es\""}, + {"rune":58,"result":"line 1, \"pala:zz\", holds U+003A, which is not in the alphabet of \"es\""}, + {"rune":59,"result":"line 1, \"pala;zz\", holds U+003B, which is not in the alphabet of \"es\""}, + {"rune":60,"result":"line 1, \"palazz\", holds U+003E, which is not in the alphabet of \"es\""}, + {"rune":63,"result":"line 1, \"pala?zz\", holds U+003F, which is not in the alphabet of \"es\""}, + {"rune":64,"result":"line 1, \"pala@zz\", holds U+0040, which is not in the alphabet of \"es\""}, + {"rune":65,"result":"line 1, \"palaAzz\", holds U+0041, which is not in the alphabet of \"es\""}, + {"rune":66,"result":"line 1, \"palaBzz\", holds U+0042, which is not in the alphabet of \"es\""}, + {"rune":67,"result":"line 1, \"palaCzz\", holds U+0043, which is not in the alphabet of \"es\""}, + {"rune":68,"result":"line 1, \"palaDzz\", holds U+0044, which is not in the alphabet of \"es\""}, + {"rune":69,"result":"line 1, \"palaEzz\", holds U+0045, which is not in the alphabet of \"es\""}, + {"rune":70,"result":"line 1, \"palaFzz\", holds U+0046, which is not in the alphabet of \"es\""}, + {"rune":71,"result":"line 1, \"palaGzz\", holds U+0047, which is not in the alphabet of \"es\""}, + {"rune":72,"result":"line 1, \"palaHzz\", holds U+0048, which is not in the alphabet of \"es\""}, + {"rune":73,"result":"line 1, \"palaIzz\", holds U+0049, which is not in the alphabet of \"es\""}, + {"rune":74,"result":"line 1, \"palaJzz\", holds U+004A, which is not in the alphabet of \"es\""}, + {"rune":75,"result":"line 1, \"palaKzz\", holds U+004B, which is not in the alphabet of \"es\""}, + {"rune":76,"result":"line 1, \"palaLzz\", holds U+004C, which is not in the alphabet of \"es\""}, + {"rune":77,"result":"line 1, \"palaMzz\", holds U+004D, which is not in the alphabet of \"es\""}, + {"rune":78,"result":"line 1, \"palaNzz\", holds U+004E, which is not in the alphabet of \"es\""}, + {"rune":79,"result":"line 1, \"palaOzz\", holds U+004F, which is not in the alphabet of \"es\""}, + {"rune":80,"result":"line 1, \"palaPzz\", holds U+0050, which is not in the alphabet of \"es\""}, + {"rune":81,"result":"line 1, \"palaQzz\", holds U+0051, which is not in the alphabet of \"es\""}, + {"rune":82,"result":"line 1, \"palaRzz\", holds U+0052, which is not in the alphabet of \"es\""}, + {"rune":83,"result":"line 1, \"palaSzz\", holds U+0053, which is not in the alphabet of \"es\""}, + {"rune":84,"result":"line 1, \"palaTzz\", holds U+0054, which is not in the alphabet of \"es\""}, + {"rune":85,"result":"line 1, \"palaUzz\", holds U+0055, which is not in the alphabet of \"es\""}, + {"rune":86,"result":"line 1, \"palaVzz\", holds U+0056, which is not in the alphabet of \"es\""}, + {"rune":87,"result":"line 1, \"palaWzz\", holds U+0057, which is not in the alphabet of \"es\""}, + {"rune":88,"result":"line 1, \"palaXzz\", holds U+0058, which is not in the alphabet of \"es\""}, + {"rune":89,"result":"line 1, \"palaYzz\", holds U+0059, which is not in the alphabet of \"es\""}, + {"rune":90,"result":"line 1, \"palaZzz\", holds U+005A, which is not in the alphabet of \"es\""}, + {"rune":91,"result":"line 1, \"pala[zz\", holds U+005B, which is not in the alphabet of \"es\""}, + {"rune":92,"result":"line 1, \"pala\\\\zz\", holds U+005C, which is not in the alphabet of \"es\""}, + {"rune":93,"result":"line 1, \"pala]zz\", holds U+005D, which is not in the alphabet of \"es\""}, + {"rune":94,"result":"line 1, \"pala^zz\", holds U+005E, which is not in the alphabet of \"es\""}, + {"rune":95,"result":"line 1, \"pala_zz\", holds U+005F, which is not in the alphabet of \"es\""}, + {"rune":96,"result":"line 1, \"pala`zz\", holds U+0060, which is not in the alphabet of \"es\""}, + {"rune":97,"result":"ok"}, + {"rune":98,"result":"ok"}, + {"rune":99,"result":"ok"}, + {"rune":100,"result":"ok"}, + {"rune":101,"result":"ok"}, + {"rune":102,"result":"ok"}, + {"rune":103,"result":"ok"}, + {"rune":104,"result":"ok"}, + {"rune":105,"result":"ok"}, + {"rune":106,"result":"ok"}, + {"rune":107,"result":"ok"}, + {"rune":108,"result":"ok"}, + {"rune":109,"result":"ok"}, + {"rune":110,"result":"ok"}, + {"rune":111,"result":"ok"}, + {"rune":112,"result":"ok"}, + {"rune":113,"result":"ok"}, + {"rune":114,"result":"ok"}, + {"rune":115,"result":"ok"}, + {"rune":116,"result":"ok"}, + {"rune":117,"result":"ok"}, + {"rune":118,"result":"ok"}, + {"rune":119,"result":"ok"}, + {"rune":120,"result":"ok"}, + {"rune":121,"result":"ok"}, + {"rune":122,"result":"ok"}, + {"rune":123,"result":"line 1, \"pala{zz\", holds U+007B, which is not in the alphabet of \"es\""}, + {"rune":124,"result":"line 1, \"pala|zz\", holds U+007C, which is not in the alphabet of \"es\""}, + {"rune":125,"result":"line 1, \"pala}zz\", holds U+007D, which is not in the alphabet of \"es\""}, + {"rune":126,"result":"line 1, \"pala~zz\", holds U+007E, which is not in the alphabet of \"es\""}, + {"rune":127,"result":"line 1: wordkey: the words hold the control character U+007F"}, + {"rune":128,"result":"line 1: wordkey: the words hold the control character U+0080"}, + {"rune":129,"result":"line 1: wordkey: the words hold the control character U+0081"}, + {"rune":130,"result":"line 1: wordkey: the words hold the control character U+0082"}, + {"rune":131,"result":"line 1: wordkey: the words hold the control character U+0083"}, + {"rune":132,"result":"line 1: wordkey: the words hold the control character U+0084"}, + {"rune":133,"result":"line 1, \"pala\\u0085zz\", is not one word of 3 or more letters"}, + {"rune":134,"result":"line 1: wordkey: the words hold the control character U+0086"}, + {"rune":135,"result":"line 1: wordkey: the words hold the control character U+0087"}, + {"rune":136,"result":"line 1: wordkey: the words hold the control character U+0088"}, + {"rune":137,"result":"line 1: wordkey: the words hold the control character U+0089"}, + {"rune":138,"result":"line 1: wordkey: the words hold the control character U+008A"}, + {"rune":139,"result":"line 1: wordkey: the words hold the control character U+008B"}, + {"rune":140,"result":"line 1: wordkey: the words hold the control character U+008C"}, + {"rune":141,"result":"line 1: wordkey: the words hold the control character U+008D"}, + {"rune":142,"result":"line 1: wordkey: the words hold the control character U+008E"}, + {"rune":143,"result":"line 1: wordkey: the words hold the control character U+008F"}, + {"rune":144,"result":"line 1: wordkey: the words hold the control character U+0090"}, + {"rune":145,"result":"line 1: wordkey: the words hold the control character U+0091"}, + {"rune":146,"result":"line 1: wordkey: the words hold the control character U+0092"}, + {"rune":147,"result":"line 1: wordkey: the words hold the control character U+0093"}, + {"rune":148,"result":"line 1: wordkey: the words hold the control character U+0094"}, + {"rune":149,"result":"line 1: wordkey: the words hold the control character U+0095"}, + {"rune":150,"result":"line 1: wordkey: the words hold the control character U+0096"}, + {"rune":151,"result":"line 1: wordkey: the words hold the control character U+0097"}, + {"rune":152,"result":"line 1: wordkey: the words hold the control character U+0098"}, + {"rune":153,"result":"line 1: wordkey: the words hold the control character U+0099"}, + {"rune":154,"result":"line 1: wordkey: the words hold the control character U+009A"}, + {"rune":155,"result":"line 1: wordkey: the words hold the control character U+009B"}, + {"rune":156,"result":"line 1: wordkey: the words hold the control character U+009C"}, + {"rune":157,"result":"line 1: wordkey: the words hold the control character U+009D"}, + {"rune":158,"result":"line 1: wordkey: the words hold the control character U+009E"}, + {"rune":159,"result":"line 1: wordkey: the words hold the control character U+009F"}, + {"rune":160,"result":"line 1, \"pala\\u00a0zz\", is not one word of 3 or more letters"}, + {"rune":161,"result":"line 1, \"pala\u00a1zz\", holds U+00A1, which is not in the alphabet of \"es\""}, + {"rune":162,"result":"line 1, \"pala\u00a2zz\", holds U+00A2, which is not in the alphabet of \"es\""}, + {"rune":163,"result":"line 1, \"pala\u00a3zz\", holds U+00A3, which is not in the alphabet of \"es\""}, + {"rune":164,"result":"line 1, \"pala\u00a4zz\", holds U+00A4, which is not in the alphabet of \"es\""}, + {"rune":165,"result":"line 1, \"pala\u00a5zz\", holds U+00A5, which is not in the alphabet of \"es\""}, + {"rune":166,"result":"line 1, \"pala\u00a6zz\", holds U+00A6, which is not in the alphabet of \"es\""}, + {"rune":167,"result":"line 1, \"pala\u00a7zz\", holds U+00A7, which is not in the alphabet of \"es\""}, + {"rune":168,"result":"line 1, \"pala\u00a8zz\", holds U+00A8, which is not in the alphabet of \"es\""}, + {"rune":169,"result":"line 1, \"pala\u00a9zz\", holds U+00A9, which is not in the alphabet of \"es\""}, + {"rune":170,"result":"line 1, \"pala\u00aazz\", holds U+00AA, which is not in the alphabet of \"es\""}, + {"rune":171,"result":"line 1, \"pala\u00abzz\", holds U+00AB, which is not in the alphabet of \"es\""}, + {"rune":172,"result":"line 1, \"pala\u00aczz\", holds U+00AC, which is not in the alphabet of \"es\""}, + {"rune":173,"result":"line 1: wordkey: the words hold the invisible character U+00AD"}, + {"rune":174,"result":"line 1, \"pala\u00aezz\", holds U+00AE, which is not in the alphabet of \"es\""}, + {"rune":175,"result":"line 1, \"pala\u00afzz\", holds U+00AF, which is not in the alphabet of \"es\""}, + {"rune":176,"result":"line 1, \"pala\u00b0zz\", holds U+00B0, which is not in the alphabet of \"es\""}, + {"rune":177,"result":"line 1, \"pala\u00b1zz\", holds U+00B1, which is not in the alphabet of \"es\""}, + {"rune":178,"result":"line 1, \"pala\u00b2zz\", holds U+00B2, which is not in the alphabet of \"es\""}, + {"rune":179,"result":"line 1, \"pala\u00b3zz\", holds U+00B3, which is not in the alphabet of \"es\""}, + {"rune":180,"result":"line 1, \"pala\u00b4zz\", holds U+00B4, which is not in the alphabet of \"es\""}, + {"rune":181,"result":"line 1, \"pala\u00b5zz\", holds U+00B5, which is not in the alphabet of \"es\""}, + {"rune":182,"result":"line 1, \"pala\u00b6zz\", holds U+00B6, which is not in the alphabet of \"es\""}, + {"rune":183,"result":"line 1, \"pala\u00b7zz\", holds U+00B7, which is not in the alphabet of \"es\""}, + {"rune":184,"result":"line 1, \"pala\u00b8zz\", holds U+00B8, which is not in the alphabet of \"es\""}, + {"rune":185,"result":"line 1, \"pala\u00b9zz\", holds U+00B9, which is not in the alphabet of \"es\""}, + {"rune":186,"result":"line 1, \"pala\u00bazz\", holds U+00BA, which is not in the alphabet of \"es\""}, + {"rune":187,"result":"line 1, \"pala\u00bbzz\", holds U+00BB, which is not in the alphabet of \"es\""}, + {"rune":188,"result":"line 1, \"pala\u00bczz\", holds U+00BC, which is not in the alphabet of \"es\""}, + {"rune":189,"result":"line 1, \"pala\u00bdzz\", holds U+00BD, which is not in the alphabet of \"es\""}, + {"rune":190,"result":"line 1, \"pala\u00bezz\", holds U+00BE, which is not in the alphabet of \"es\""}, + {"rune":191,"result":"line 1, \"pala\u00bfzz\", holds U+00BF, which is not in the alphabet of \"es\""}, + {"rune":192,"result":"line 1, \"pala\u00c0zz\", holds U+00C0, which is not in the alphabet of \"es\""}, + {"rune":193,"result":"line 1, \"pala\u00c1zz\", holds U+00C1, which is not in the alphabet of \"es\""}, + {"rune":194,"result":"line 1, \"pala\u00c2zz\", holds U+00C2, which is not in the alphabet of \"es\""}, + {"rune":195,"result":"line 1, \"pala\u00c3zz\", holds U+00C3, which is not in the alphabet of \"es\""}, + {"rune":196,"result":"line 1, \"pala\u00c4zz\", holds U+00C4, which is not in the alphabet of \"es\""}, + {"rune":197,"result":"line 1, \"pala\u00c5zz\", holds U+00C5, which is not in the alphabet of \"es\""}, + {"rune":198,"result":"line 1, \"pala\u00c6zz\", holds U+00C6, which is not in the alphabet of \"es\""}, + {"rune":199,"result":"line 1, \"pala\u00c7zz\", holds U+00C7, which is not in the alphabet of \"es\""}, + {"rune":200,"result":"line 1, \"pala\u00c8zz\", holds U+00C8, which is not in the alphabet of \"es\""}, + {"rune":201,"result":"line 1, \"pala\u00c9zz\", holds U+00C9, which is not in the alphabet of \"es\""}, + {"rune":202,"result":"line 1, \"pala\u00cazz\", holds U+00CA, which is not in the alphabet of \"es\""}, + {"rune":203,"result":"line 1, \"pala\u00cbzz\", holds U+00CB, which is not in the alphabet of \"es\""}, + {"rune":204,"result":"line 1, \"pala\u00cczz\", holds U+00CC, which is not in the alphabet of \"es\""}, + {"rune":205,"result":"line 1, \"pala\u00cdzz\", holds U+00CD, which is not in the alphabet of \"es\""}, + {"rune":206,"result":"line 1, \"pala\u00cezz\", holds U+00CE, which is not in the alphabet of \"es\""}, + {"rune":207,"result":"line 1, \"pala\u00cfzz\", holds U+00CF, which is not in the alphabet of \"es\""}, + {"rune":208,"result":"line 1, \"pala\u00d0zz\", holds U+00D0, which is not in the alphabet of \"es\""}, + {"rune":209,"result":"line 1, \"pala\u00d1zz\", holds U+00D1, which is not in the alphabet of \"es\""}, + {"rune":210,"result":"line 1, \"pala\u00d2zz\", holds U+00D2, which is not in the alphabet of \"es\""}, + {"rune":211,"result":"line 1, \"pala\u00d3zz\", holds U+00D3, which is not in the alphabet of \"es\""}, + {"rune":212,"result":"line 1, \"pala\u00d4zz\", holds U+00D4, which is not in the alphabet of \"es\""}, + {"rune":213,"result":"line 1, \"pala\u00d5zz\", holds U+00D5, which is not in the alphabet of \"es\""}, + {"rune":214,"result":"line 1, \"pala\u00d6zz\", holds U+00D6, which is not in the alphabet of \"es\""}, + {"rune":215,"result":"line 1, \"pala\u00d7zz\", holds U+00D7, which is not in the alphabet of \"es\""}, + {"rune":216,"result":"line 1, \"pala\u00d8zz\", holds U+00D8, which is not in the alphabet of \"es\""}, + {"rune":217,"result":"line 1, \"pala\u00d9zz\", holds U+00D9, which is not in the alphabet of \"es\""}, + {"rune":218,"result":"line 1, \"pala\u00dazz\", holds U+00DA, which is not in the alphabet of \"es\""}, + {"rune":219,"result":"line 1, \"pala\u00dbzz\", holds U+00DB, which is not in the alphabet of \"es\""}, + {"rune":220,"result":"line 1, \"pala\u00dczz\", holds U+00DC, which is not in the alphabet of \"es\""}, + {"rune":221,"result":"line 1, \"pala\u00ddzz\", holds U+00DD, which is not in the alphabet of \"es\""}, + {"rune":222,"result":"line 1, \"pala\u00dezz\", holds U+00DE, which is not in the alphabet of \"es\""}, + {"rune":223,"result":"line 1, \"pala\u00dfzz\", holds U+00DF, which is not in the alphabet of \"es\""}, + {"rune":224,"result":"line 1, \"pala\u00e0zz\", holds U+00E0, which is not in the alphabet of \"es\""}, + {"rune":225,"result":"ok"}, + {"rune":226,"result":"line 1, \"pala\u00e2zz\", holds U+00E2, which is not in the alphabet of \"es\""}, + {"rune":227,"result":"line 1, \"pala\u00e3zz\", holds U+00E3, which is not in the alphabet of \"es\""}, + {"rune":228,"result":"line 1, \"pala\u00e4zz\", holds U+00E4, which is not in the alphabet of \"es\""}, + {"rune":229,"result":"line 1, \"pala\u00e5zz\", holds U+00E5, which is not in the alphabet of \"es\""}, + {"rune":230,"result":"line 1, \"pala\u00e6zz\", holds U+00E6, which is not in the alphabet of \"es\""}, + {"rune":231,"result":"line 1, \"pala\u00e7zz\", holds U+00E7, which is not in the alphabet of \"es\""}, + {"rune":232,"result":"line 1, \"pala\u00e8zz\", holds U+00E8, which is not in the alphabet of \"es\""}, + {"rune":233,"result":"ok"}, + {"rune":234,"result":"line 1, \"pala\u00eazz\", holds U+00EA, which is not in the alphabet of \"es\""}, + {"rune":235,"result":"line 1, \"pala\u00ebzz\", holds U+00EB, which is not in the alphabet of \"es\""}, + {"rune":236,"result":"line 1, \"pala\u00eczz\", holds U+00EC, which is not in the alphabet of \"es\""}, + {"rune":237,"result":"ok"}, + {"rune":238,"result":"line 1, \"pala\u00eezz\", holds U+00EE, which is not in the alphabet of \"es\""}, + {"rune":239,"result":"line 1, \"pala\u00efzz\", holds U+00EF, which is not in the alphabet of \"es\""}, + {"rune":240,"result":"line 1, \"pala\u00f0zz\", holds U+00F0, which is not in the alphabet of \"es\""}, + {"rune":241,"result":"ok"}, + {"rune":242,"result":"line 1, \"pala\u00f2zz\", holds U+00F2, which is not in the alphabet of \"es\""}, + {"rune":243,"result":"ok"}, + {"rune":244,"result":"line 1, \"pala\u00f4zz\", holds U+00F4, which is not in the alphabet of \"es\""}, + {"rune":245,"result":"line 1, \"pala\u00f5zz\", holds U+00F5, which is not in the alphabet of \"es\""}, + {"rune":246,"result":"line 1, \"pala\u00f6zz\", holds U+00F6, which is not in the alphabet of \"es\""}, + {"rune":247,"result":"line 1, \"pala\u00f7zz\", holds U+00F7, which is not in the alphabet of \"es\""}, + {"rune":248,"result":"line 1, \"pala\u00f8zz\", holds U+00F8, which is not in the alphabet of \"es\""}, + {"rune":249,"result":"line 1, \"pala\u00f9zz\", holds U+00F9, which is not in the alphabet of \"es\""}, + {"rune":250,"result":"ok"}, + {"rune":251,"result":"line 1, \"pala\u00fbzz\", holds U+00FB, which is not in the alphabet of \"es\""}, + {"rune":252,"result":"ok"}, + {"rune":253,"result":"line 1, \"pala\u00fdzz\", holds U+00FD, which is not in the alphabet of \"es\""}, + {"rune":254,"result":"line 1, \"pala\u00fezz\", holds U+00FE, which is not in the alphabet of \"es\""}, + {"rune":255,"result":"line 1, \"pala\u00ffzz\", holds U+00FF, which is not in the alphabet of \"es\""}, + {"rune":256,"result":"line 1, \"pala\u0100zz\", holds U+0100, which is not in the alphabet of \"es\""}, + {"rune":257,"result":"line 1, \"pala\u0101zz\", holds U+0101, which is not in the alphabet of \"es\""}, + {"rune":258,"result":"line 1, \"pala\u0102zz\", holds U+0102, which is not in the alphabet of \"es\""}, + {"rune":259,"result":"line 1, \"pala\u0103zz\", holds U+0103, which is not in the alphabet of \"es\""}, + {"rune":260,"result":"line 1, \"pala\u0104zz\", holds U+0104, which is not in the alphabet of \"es\""}, + {"rune":261,"result":"line 1, \"pala\u0105zz\", holds U+0105, which is not in the alphabet of \"es\""}, + {"rune":262,"result":"line 1, \"pala\u0106zz\", holds U+0106, which is not in the alphabet of \"es\""}, + {"rune":263,"result":"line 1, \"pala\u0107zz\", holds U+0107, which is not in the alphabet of \"es\""}, + {"rune":264,"result":"line 1, \"pala\u0108zz\", holds U+0108, which is not in the alphabet of \"es\""}, + {"rune":265,"result":"line 1, \"pala\u0109zz\", holds U+0109, which is not in the alphabet of \"es\""}, + {"rune":266,"result":"line 1, \"pala\u010azz\", holds U+010A, which is not in the alphabet of \"es\""}, + {"rune":267,"result":"line 1, \"pala\u010bzz\", holds U+010B, which is not in the alphabet of \"es\""}, + {"rune":268,"result":"line 1, \"pala\u010czz\", holds U+010C, which is not in the alphabet of \"es\""}, + {"rune":269,"result":"line 1, \"pala\u010dzz\", holds U+010D, which is not in the alphabet of \"es\""}, + {"rune":270,"result":"line 1, \"pala\u010ezz\", holds U+010E, which is not in the alphabet of \"es\""}, + {"rune":271,"result":"line 1, \"pala\u010fzz\", holds U+010F, which is not in the alphabet of \"es\""}, + {"rune":272,"result":"line 1, \"pala\u0110zz\", holds U+0110, which is not in the alphabet of \"es\""}, + {"rune":273,"result":"line 1, \"pala\u0111zz\", holds U+0111, which is not in the alphabet of \"es\""}, + {"rune":274,"result":"line 1, \"pala\u0112zz\", holds U+0112, which is not in the alphabet of \"es\""}, + {"rune":275,"result":"line 1, \"pala\u0113zz\", holds U+0113, which is not in the alphabet of \"es\""}, + {"rune":276,"result":"line 1, \"pala\u0114zz\", holds U+0114, which is not in the alphabet of \"es\""}, + {"rune":277,"result":"line 1, \"pala\u0115zz\", holds U+0115, which is not in the alphabet of \"es\""}, + {"rune":278,"result":"line 1, \"pala\u0116zz\", holds U+0116, which is not in the alphabet of \"es\""}, + {"rune":279,"result":"line 1, \"pala\u0117zz\", holds U+0117, which is not in the alphabet of \"es\""}, + {"rune":280,"result":"line 1, \"pala\u0118zz\", holds U+0118, which is not in the alphabet of \"es\""}, + {"rune":281,"result":"line 1, \"pala\u0119zz\", holds U+0119, which is not in the alphabet of \"es\""}, + {"rune":282,"result":"line 1, \"pala\u011azz\", holds U+011A, which is not in the alphabet of \"es\""}, + {"rune":283,"result":"line 1, \"pala\u011bzz\", holds U+011B, which is not in the alphabet of \"es\""}, + {"rune":284,"result":"line 1, \"pala\u011czz\", holds U+011C, which is not in the alphabet of \"es\""}, + {"rune":285,"result":"line 1, \"pala\u011dzz\", holds U+011D, which is not in the alphabet of \"es\""}, + {"rune":286,"result":"line 1, \"pala\u011ezz\", holds U+011E, which is not in the alphabet of \"es\""}, + {"rune":287,"result":"line 1, \"pala\u011fzz\", holds U+011F, which is not in the alphabet of \"es\""}, + {"rune":288,"result":"line 1, \"pala\u0120zz\", holds U+0120, which is not in the alphabet of \"es\""}, + {"rune":289,"result":"line 1, \"pala\u0121zz\", holds U+0121, which is not in the alphabet of \"es\""}, + {"rune":290,"result":"line 1, \"pala\u0122zz\", holds U+0122, which is not in the alphabet of \"es\""}, + {"rune":291,"result":"line 1, \"pala\u0123zz\", holds U+0123, which is not in the alphabet of \"es\""}, + {"rune":292,"result":"line 1, \"pala\u0124zz\", holds U+0124, which is not in the alphabet of \"es\""}, + {"rune":293,"result":"line 1, \"pala\u0125zz\", holds U+0125, which is not in the alphabet of \"es\""}, + {"rune":294,"result":"line 1, \"pala\u0126zz\", holds U+0126, which is not in the alphabet of \"es\""}, + {"rune":295,"result":"line 1, \"pala\u0127zz\", holds U+0127, which is not in the alphabet of \"es\""}, + {"rune":296,"result":"line 1, \"pala\u0128zz\", holds U+0128, which is not in the alphabet of \"es\""}, + {"rune":297,"result":"line 1, \"pala\u0129zz\", holds U+0129, which is not in the alphabet of \"es\""}, + {"rune":298,"result":"line 1, \"pala\u012azz\", holds U+012A, which is not in the alphabet of \"es\""}, + {"rune":299,"result":"line 1, \"pala\u012bzz\", holds U+012B, which is not in the alphabet of \"es\""}, + {"rune":300,"result":"line 1, \"pala\u012czz\", holds U+012C, which is not in the alphabet of \"es\""}, + {"rune":301,"result":"line 1, \"pala\u012dzz\", holds U+012D, which is not in the alphabet of \"es\""}, + {"rune":302,"result":"line 1, \"pala\u012ezz\", holds U+012E, which is not in the alphabet of \"es\""}, + {"rune":303,"result":"line 1, \"pala\u012fzz\", holds U+012F, which is not in the alphabet of \"es\""}, + {"rune":304,"result":"line 1, \"pala\u0130zz\", holds U+0130, which is not in the alphabet of \"es\""}, + {"rune":305,"result":"line 1, \"pala\u0131zz\", holds U+0131, which is not in the alphabet of \"es\""}, + {"rune":306,"result":"line 1, \"pala\u0132zz\", holds U+0132, which is not in the alphabet of \"es\""}, + {"rune":307,"result":"line 1, \"pala\u0133zz\", holds U+0133, which is not in the alphabet of \"es\""}, + {"rune":308,"result":"line 1, \"pala\u0134zz\", holds U+0134, which is not in the alphabet of \"es\""}, + {"rune":309,"result":"line 1, \"pala\u0135zz\", holds U+0135, which is not in the alphabet of \"es\""}, + {"rune":310,"result":"line 1, \"pala\u0136zz\", holds U+0136, which is not in the alphabet of \"es\""}, + {"rune":311,"result":"line 1, \"pala\u0137zz\", holds U+0137, which is not in the alphabet of \"es\""}, + {"rune":312,"result":"line 1, \"pala\u0138zz\", holds U+0138, which is not in the alphabet of \"es\""}, + {"rune":313,"result":"line 1, \"pala\u0139zz\", holds U+0139, which is not in the alphabet of \"es\""}, + {"rune":314,"result":"line 1, \"pala\u013azz\", holds U+013A, which is not in the alphabet of \"es\""}, + {"rune":315,"result":"line 1, \"pala\u013bzz\", holds U+013B, which is not in the alphabet of \"es\""}, + {"rune":316,"result":"line 1, \"pala\u013czz\", holds U+013C, which is not in the alphabet of \"es\""}, + {"rune":317,"result":"line 1, \"pala\u013dzz\", holds U+013D, which is not in the alphabet of \"es\""}, + {"rune":318,"result":"line 1, \"pala\u013ezz\", holds U+013E, which is not in the alphabet of \"es\""}, + {"rune":319,"result":"line 1, \"pala\u013fzz\", holds U+013F, which is not in the alphabet of \"es\""}, + {"rune":320,"result":"line 1, \"pala\u0140zz\", holds U+0140, which is not in the alphabet of \"es\""}, + {"rune":321,"result":"line 1, \"pala\u0141zz\", holds U+0141, which is not in the alphabet of \"es\""}, + {"rune":322,"result":"line 1, \"pala\u0142zz\", holds U+0142, which is not in the alphabet of \"es\""}, + {"rune":323,"result":"line 1, \"pala\u0143zz\", holds U+0143, which is not in the alphabet of \"es\""}, + {"rune":324,"result":"line 1, \"pala\u0144zz\", holds U+0144, which is not in the alphabet of \"es\""}, + {"rune":325,"result":"line 1, \"pala\u0145zz\", holds U+0145, which is not in the alphabet of \"es\""}, + {"rune":326,"result":"line 1, \"pala\u0146zz\", holds U+0146, which is not in the alphabet of \"es\""}, + {"rune":327,"result":"line 1, \"pala\u0147zz\", holds U+0147, which is not in the alphabet of \"es\""}, + {"rune":328,"result":"line 1, \"pala\u0148zz\", holds U+0148, which is not in the alphabet of \"es\""}, + {"rune":329,"result":"line 1, \"pala\u0149zz\", holds U+0149, which is not in the alphabet of \"es\""}, + {"rune":330,"result":"line 1, \"pala\u014azz\", holds U+014A, which is not in the alphabet of \"es\""}, + {"rune":331,"result":"line 1, \"pala\u014bzz\", holds U+014B, which is not in the alphabet of \"es\""}, + {"rune":332,"result":"line 1, \"pala\u014czz\", holds U+014C, which is not in the alphabet of \"es\""}, + {"rune":333,"result":"line 1, \"pala\u014dzz\", holds U+014D, which is not in the alphabet of \"es\""}, + {"rune":334,"result":"line 1, \"pala\u014ezz\", holds U+014E, which is not in the alphabet of \"es\""}, + {"rune":335,"result":"line 1, \"pala\u014fzz\", holds U+014F, which is not in the alphabet of \"es\""}, + {"rune":336,"result":"line 1, \"pala\u0150zz\", holds U+0150, which is not in the alphabet of \"es\""}, + {"rune":337,"result":"line 1, \"pala\u0151zz\", holds U+0151, which is not in the alphabet of \"es\""}, + {"rune":338,"result":"line 1, \"pala\u0152zz\", holds U+0152, which is not in the alphabet of \"es\""}, + {"rune":339,"result":"line 1, \"pala\u0153zz\", holds U+0153, which is not in the alphabet of \"es\""}, + {"rune":340,"result":"line 1, \"pala\u0154zz\", holds U+0154, which is not in the alphabet of \"es\""}, + {"rune":341,"result":"line 1, \"pala\u0155zz\", holds U+0155, which is not in the alphabet of \"es\""}, + {"rune":342,"result":"line 1, \"pala\u0156zz\", holds U+0156, which is not in the alphabet of \"es\""}, + {"rune":343,"result":"line 1, \"pala\u0157zz\", holds U+0157, which is not in the alphabet of \"es\""}, + {"rune":344,"result":"line 1, \"pala\u0158zz\", holds U+0158, which is not in the alphabet of \"es\""}, + {"rune":345,"result":"line 1, \"pala\u0159zz\", holds U+0159, which is not in the alphabet of \"es\""}, + {"rune":346,"result":"line 1, \"pala\u015azz\", holds U+015A, which is not in the alphabet of \"es\""}, + {"rune":347,"result":"line 1, \"pala\u015bzz\", holds U+015B, which is not in the alphabet of \"es\""}, + {"rune":348,"result":"line 1, \"pala\u015czz\", holds U+015C, which is not in the alphabet of \"es\""}, + {"rune":349,"result":"line 1, \"pala\u015dzz\", holds U+015D, which is not in the alphabet of \"es\""}, + {"rune":350,"result":"line 1, \"pala\u015ezz\", holds U+015E, which is not in the alphabet of \"es\""}, + {"rune":351,"result":"line 1, \"pala\u015fzz\", holds U+015F, which is not in the alphabet of \"es\""}, + {"rune":352,"result":"line 1, \"pala\u0160zz\", holds U+0160, which is not in the alphabet of \"es\""}, + {"rune":353,"result":"line 1, \"pala\u0161zz\", holds U+0161, which is not in the alphabet of \"es\""}, + {"rune":354,"result":"line 1, \"pala\u0162zz\", holds U+0162, which is not in the alphabet of \"es\""}, + {"rune":355,"result":"line 1, \"pala\u0163zz\", holds U+0163, which is not in the alphabet of \"es\""}, + {"rune":356,"result":"line 1, \"pala\u0164zz\", holds U+0164, which is not in the alphabet of \"es\""}, + {"rune":357,"result":"line 1, \"pala\u0165zz\", holds U+0165, which is not in the alphabet of \"es\""}, + {"rune":358,"result":"line 1, \"pala\u0166zz\", holds U+0166, which is not in the alphabet of \"es\""}, + {"rune":359,"result":"line 1, \"pala\u0167zz\", holds U+0167, which is not in the alphabet of \"es\""}, + {"rune":360,"result":"line 1, \"pala\u0168zz\", holds U+0168, which is not in the alphabet of \"es\""}, + {"rune":361,"result":"line 1, \"pala\u0169zz\", holds U+0169, which is not in the alphabet of \"es\""}, + {"rune":362,"result":"line 1, \"pala\u016azz\", holds U+016A, which is not in the alphabet of \"es\""}, + {"rune":363,"result":"line 1, \"pala\u016bzz\", holds U+016B, which is not in the alphabet of \"es\""}, + {"rune":364,"result":"line 1, \"pala\u016czz\", holds U+016C, which is not in the alphabet of \"es\""}, + {"rune":365,"result":"line 1, \"pala\u016dzz\", holds U+016D, which is not in the alphabet of \"es\""}, + {"rune":366,"result":"line 1, \"pala\u016ezz\", holds U+016E, which is not in the alphabet of \"es\""}, + {"rune":367,"result":"line 1, \"pala\u016fzz\", holds U+016F, which is not in the alphabet of \"es\""}, + {"rune":368,"result":"line 1, \"pala\u0170zz\", holds U+0170, which is not in the alphabet of \"es\""}, + {"rune":369,"result":"line 1, \"pala\u0171zz\", holds U+0171, which is not in the alphabet of \"es\""}, + {"rune":370,"result":"line 1, \"pala\u0172zz\", holds U+0172, which is not in the alphabet of \"es\""}, + {"rune":371,"result":"line 1, \"pala\u0173zz\", holds U+0173, which is not in the alphabet of \"es\""}, + {"rune":372,"result":"line 1, \"pala\u0174zz\", holds U+0174, which is not in the alphabet of \"es\""}, + {"rune":373,"result":"line 1, \"pala\u0175zz\", holds U+0175, which is not in the alphabet of \"es\""}, + {"rune":374,"result":"line 1, \"pala\u0176zz\", holds U+0176, which is not in the alphabet of \"es\""}, + {"rune":375,"result":"line 1, \"pala\u0177zz\", holds U+0177, which is not in the alphabet of \"es\""}, + {"rune":376,"result":"line 1, \"pala\u0178zz\", holds U+0178, which is not in the alphabet of \"es\""}, + {"rune":377,"result":"line 1, \"pala\u0179zz\", holds U+0179, which is not in the alphabet of \"es\""}, + {"rune":378,"result":"line 1, \"pala\u017azz\", holds U+017A, which is not in the alphabet of \"es\""}, + {"rune":379,"result":"line 1, \"pala\u017bzz\", holds U+017B, which is not in the alphabet of \"es\""}, + {"rune":380,"result":"line 1, \"pala\u017czz\", holds U+017C, which is not in the alphabet of \"es\""}, + {"rune":381,"result":"line 1, \"pala\u017dzz\", holds U+017D, which is not in the alphabet of \"es\""}, + {"rune":382,"result":"line 1, \"pala\u017ezz\", holds U+017E, which is not in the alphabet of \"es\""}, + {"rune":383,"result":"line 1, \"pala\u017fzz\", holds U+017F, which is not in the alphabet of \"es\""} + ], + "generate": [ + {"name":"6 words of the Spanish list","list":"es","size":7776,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate es 6"},"indices":[7552,321,1677,3637,3081,2378],"words":["vertebral","almirante","cojonudo","habla","ex\u00f3tico","diez"],"read":12,"next":"eb4e23cd"}, + {"name":"7 words of the Spanish list","list":"es","size":7776,"n":7,"stream":{"kind":"seeded","seed":"wordkey.Generate es 7"},"indices":[121,5143,3291,9,13,6590,1402],"words":["adecuado","obsequio","forzar","abejorro","abofetear","sargento","cava"],"read":14,"next":"15c97f0a"}, + {"name":"8 words of the Spanish list","list":"es","size":7776,"n":8,"stream":{"kind":"seeded","seed":"wordkey.Generate es 8"},"indices":[7419,3418,7185,4830,7558,168,7028,3097],"words":["usado","gamba","tobillo","mongol","vestidor","afeminado","tardanza","faja"],"read":16,"next":"c83ca329"}, + {"name":"12 words of the Spanish list","list":"es","size":7776,"n":12,"stream":{"kind":"seeded","seed":"wordkey.Generate es 12"},"indices":[3086,1561,5885,1894,7092,3918,7535,1859,3391,4059,7054,1332],"words":["fachada","cicatriz","prodigio","coqueta","tener","infancia","verbena","contable","f\u00f3sil","jaque","tejido","carn\u00edvoro"],"read":24,"next":"78624c9c"}, + {"name":"24 words of the Spanish list","list":"es","size":7776,"n":24,"stream":{"kind":"seeded","seed":"wordkey.Generate es 24"},"indices":[7726,1419,6867,1744,1845,923,7735,5731,4412,2730,924,7147,7166,2923,5612,5119,1213,4184,276,4448,5476,2429,7382,5994],"words":["zumo","cebolla","sport","comit\u00e9","consorcio","bestial","\u00e1mbito","polilla","l\u00f3gica","enigma","beta","tic","tinta","estafador","piedra","nutria","camerino","lat\u00edn","alc\u00e1ntara","magneto","pegar","dise\u00f1o","t\u00e1ctica","puzle"],"read":50,"next":"ce61e5db"}, + {"name":"6 words of the Spanish list, SHA-256 counter blocks","list":"es","size":7776,"n":6,"stream":{"kind":"counter","seed":"wordkey.Generate counter 6"},"indices":[1614,4473,6701,7267,3452,1442],"words":["claudia","maligno","setiembre","trasladar","gaveta","cenicero"],"read":14,"next":"4a80956b"}, + {"name":"7 words of the Spanish list, SHA-256 counter blocks","list":"es","size":7776,"n":7,"stream":{"kind":"counter","seed":"wordkey.Generate counter 7"},"indices":[6542,1450,4854,3563,2426,2781,6846],"words":["salom\u00f3n","centrado","mon\u00f3tono","green","disecci\u00f3n","episodio","soplete"],"read":16,"next":"144001d1"}, + {"name":"12 words of the Spanish list, SHA-256 counter blocks","list":"es","size":7776,"n":12,"stream":{"kind":"counter","seed":"wordkey.Generate counter 12"},"indices":[7021,5055,1483,6826,6779,4834,3251,7164,898,4404,5319,7648],"words":["tapete","niebla","chacal","soluci\u00f3n","sirope","mono","flotante","tim\u00f3n","beb\u00e9","l\u00e1tigo","palmera","vocero"],"read":26,"next":"425e314b"}, + {"name":"3888 words of the Spanish list, the most","list":"es","size":7776,"n":3888,"stream":{"kind":"seeded","seed":"wordkey.Generate es 3888"},"indices":[109,424,5504,6382,3300,4291,234,5711,1211,7623,2219,264,2945,2139,3937,3892,3125,1445,2447,1461,6236,3631,6501,1031,661,4190,4414,3315,5349,4693,5513,2640,5767,593,3379,4296,487,6785,5936,6207,2874,715,4666,2039,4752,2027,4686,1501,7394,934,1968,3500,532,6806,7676,4042,6953,140,21,5822,3739,590,6547,2660,7554,2937,1653,1015,2949,2179,2392,2349,300,5144,565,3975,4062,5844,2110,3162,1481,758,4106,7164,2165,5134,2914,1948,1752,5221,6008,2721,265,3260,783,6350,5561,6750,2801,1573,303,699,4586,4753,164,1315,7700,6338,2162,870,2331,7098,4309,3391,5657,6819,429,7698,1542,4508,3832,6466,6540,2591,3922,4470,3770,4193,2085,6164,6484,5744,841,4354,3698,2251,7256,5424,3148,6993,576,5004,160,7200,4102,4246,5436,2791,2968,521,6471,290,3538,922,3047,284,6051,335,5831,7589,132,1823,315,3724,2211,3488,5615,2159,7443,1239,7399,1216,6981,3680,4702,3471,5860,7134,6610,6875,6612,5330,918,2840,6768,1382,5131,5415,4885,6701,7386,3385,6983,4798,1104,4687,1611,4101,3521,4675,5996,2160,6633,98,7361,3753,385,6128,24,6183,3849,4347,1060,4075,4284,3016,2002,3475,431,5042,1850,604,6238,1558,1640,5698,4860,2539,374,5542,5136,5878,7172,3791,7511,7453,6039,3258,1578,7624,1909,6600,2453,6258,1255,4053,2209,85,1811,4684,2461,6041,6656,3275,1930,5359,3726,7147,862,1967,1224,3117,7376,5516,6711,2855,3314,3103,1374,914,6294,1940,4377,2468,6342,3845,6299,4523,3948,332,2974,2369,7303,1271,1586,5864,2616,1528,3382,6821,7398,2063,742,6861,2490,3108,319,4800,7419,6689,3659,2270,1588,2627,7101,236,4942,503,3859,5481,6917,376,415,4852,7703,229,5875,4832,2381,480,3782,4541,243,678,1636,2001,3263,3618,837,4987,5676,2283,2249,5977,6948,3685,4493,2609,6625,7364,3968,1582,1829,6156,3908,3588,1851,5129,2879,1905,7683,6157,4569,5554,6687,1728,7334,2347,6161,7632,5811,4488,7718,3543,669,3418,6003,1549,5534,1956,6065,3085,7467,548,66,5324,3386,3390,4384,3862,7451,5958,2662,4997,3666,1876,4945,3064,1412,3143,443,3930,7138,5566,6494,4689,3645,7318,3989,240,2713,4780,6388,4533,6491,4253,3478,3549,7442,3637,4412,7633,4585,5148,4700,3946,974,6666,6082,4883,1296,6313,6578,6319,71,409,6918,3575,7299,4581,6997,1267,1765,722,3055,6807,150,2008,212,6590,5185,4738,6191,4046,2956,4950,6492,2711,3116,1194,4469,485,1621,7143,100,4252,6880,7756,835,3400,6949,3912,2773,2465,4868,1854,2601,203,7073,4295,2338,625,5626,5345,2115,3191,3790,3045,2077,5555,3737,6759,1303,3470,4583,3182,4338,4490,5017,916,2106,2418,117,701,7320,2520,7149,6067,4634,1603,3848,2051,3367,1134,1757,5765,13,2295,5920,3164,3636,2820,1475,3353,4882,7002,5850,111,2679,3371,4467,7103,5500,1879,7689,7711,1628,490,2282,5075,7490,7521,4876,3747,1444,6461,3282,7472,65,6052,1276,931,1385,1706,2047,3006,3643,6327,7714,334,6831,4748,6969,4906,4460,5059,4812,1226,2310,2442,626,5640,3589,207,6867,643,611,5574,3453,906,1045,6838,2473,3857,4553,7040,6853,5927,6122,5243,3082,6980,3328,4992,6648,2527,5567,7310,5808,3421,7438,6261,2878,7449,5836,364,619,7759,7309,2100,23,327,1386,4009,1160,1952,5176,4982,6279,1534,4126,291,2606,4263,3038,5952,7238,5487,4165,5925,4650,7129,47,5834,5466,1861,3993,5523,4550,4095,1231,3866,423,6954,6425,3415,7296,5579,4334,7537,3149,6770,250,1275,2519,4939,6397,1436,2626,7416,4631,1651,1939,6010,4970,7479,4312,1237,7571,5892,151,5797,4557,804,1218,5088,4838,413,7405,4803,7527,3865,627,2311,5616,1359,3765,1815,4233,1957,7304,4676,5722,4747,3461,2862,7100,7210,4408,5778,5155,6296,2074,7535,5073,5713,7673,5116,2556,4418,800,6974,2733,7091,3351,4321,4639,378,6842,2993,5391,5140,248,360,197,3183,682,2141,3950,7434,2290,2798,4242,697,7461,7509,5874,1368,3509,4292,2574,2419,2337,3526,3591,6226,6698,5807,1472,5565,6034,5480,1172,339,2748,1022,4613,2569,575,2774,1184,219,4153,4603,7563,3594,4304,5180,5437,6670,7355,4833,375,6184,1245,3334,4311,2312,6510,5897,1460,5354,2098,5545,786,7315,6511,1565,1465,705,7342,4630,6566,7533,6371,1537,6102,7491,41,6518,329,1141,3793,34,3144,6874,3073,17,5665,5337,7013,693,7679,2863,4057,3921,3043,3978,6030,76,5478,2044,5686,5695,4481,749,1055,3494,6060,7666,4216,4705,2191,3370,5630,5085,867,4957,4893,3413,6013,1607,2390,894,902,596,2725,3605,4394,6668,2206,4925,3599,6014,3702,5333,5684,6241,4373,1564,2086,5076,2498,2587,4147,4177,1450,7613,233,3327,5041,3927,4345,3032,5520,3402,3741,114,4320,4528,3703,7316,5206,997,6607,7270,1714,5524,2823,4889,1772,718,7707,6175,7608,4211,3442,6796,1119,5228,5539,113,3563,2884,1020,5411,5195,460,5412,7721,255,2484,1801,1630,2281,6672,5413,1696,2864,1457,6155,3763,2049,761,1420,2782,4520,5434,6208,4482,380,4783,6481,2833,2156,2243,3279,5224,4823,4898,3063,5182,3388,5507,2151,3903,6802,33,7369,7671,6036,1212,952,4891,739,2787,4651,6541,6302,2691,3820,4462,3052,2837,1463,989,6703,252,738,582,7344,1177,2378,2644,5334,4845,3932,2105,7245,1142,5100,5647,6531,6892,5842,5358,7558,1100,7743,6817,5364,3035,2021,3906,4994,5403,6370,449,6205,1221,3467,4751,5329,258,2999,2488,4362,4781,7401,74,578,433,2015,1340,5749,4718,6017,2978,3827,2611,2582,1259,4539,4881,4212,505,5145,900,1342,2659,2873,2356,2749,5061,6603,5685,1487,980,7716,1540,3674,3295,1524,1308,6365,4695,1975,7124,7485,4138,4826,1002,2327,5517,7090,2005,1793,6822,5336,6502,5429,4888,7611,1366,1048,7,930,4213,4730,6635,2933,1227,4236,5087,3074,6306,4850,5351,4674,4886,3942,2789,1604,389,7590,4040,5441,4789,5809,2028,4270,1005,3312,3485,4239,2213,6678,6583,5757,6789,2637,5443,4415,1446,4616,6262,7619,1822,467,3175,4302,4959,3805,5051,5499,3558,1692,5450,7477,4921,6860,2360,6852,7421,547,5225,477,3203,1836,6810,2886,7486,7469,6702,7321,4656,6232,2836,1738,752,6320,3800,4900,5320,171,885,1712,5935,3967,6747,7353,119,2250,1821,458,4342,1265,7054,1713,1409,4922,6659,320,1974,2682,2560,1434,3152,4916,134,4169,1920,6047,832,6630,2252,4020,2672,3228,417,39,5921,741,2351,3409,5493,3982,1391,2925,5060,4363,7727,5276,1470,2506,6803,3850,6245,6340,4974,2812,5891,2374,6,1327,3433,5313,2695,7351,621,2947,2515,1699,5177,3596,949,5141,3915,5872,406,4112,3341,7182,7188,3893,3900,1400,5604,3964,7109,1010,6960,5506,2835,7545,6064,7523,1643,1383,6664,860,6856,7211,1583,1993,7664,4476,2797,763,7524,2760,1390,4355,7085,4851,6210,732,7106,2279,1074,1299,2200,1864,6004,6018,4917,2990,7076,856,6432,5570,5929,7725,2867,3796,6204,1927,4256,5406,4843,5306,2948,2154,1916,1533,1188,1734,3837,1432,2808,7044,4411,3114,4073,1672,1277,4204,3981,1152,5661,2838,2758,5190,2832,1778,6957,6708,4511,3140,1684,6225,7359,1396,4310,3102,5759,7088,4375,3717,459,1006,2687,4607,4856,3544,1157,748,1281,3939,4223,3248,6290,1090,5870,648,2788,122,5728,3366,3720,6265,404,311,180,950,6771,4679,7645,5846,811,7510,4995,5907,1885,5651,1658,2330,4214,3441,1454,3094,2091,5611,2014,2397,6287,4016,3246,3755,1792,757,7672,5149,309,7690,1176,4688,4024,2939,7300,6545,4473,3337,6301,5586,5771,6944,7670,1476,143,3208,6369,3905,4855,2704,5924,7237,1825,2654,1110,3159,61,6815,3230,5108,6615,5072,3120,5299,843,3472,3612,1345,1234,2980,6505,5050,2642,6936,986,3816,5079,6273,4307,179,3578,2481,7251,7312,3305,1928,2930,6325,7053,4107,616,1186,1376,2750,3510,891,1443,2404,2841,5821,6172,7110,3169,1095,5091,4143,4787,108,1328,833,4498,5158,7146,1828,1353,5703,7411,3487,3716,6457,5163,5274,712,5147,3624,6136,6913,667,7175,68,7668,2512,2699,5550,3567,5965,5893,6333,4039,2169,4417,6214,3896,6077,3910,1181,2735,2882,5553,910,5544,5990,4485,4867,3603,799,5982,3902,6926,3520,2380,5560,1004,4068,402,4779,4953,1880,2436,1235,6513,7555,4122,2304,6922,4790,2072,7724,6645,6192,659,326,3719,1538,4081,2092,2455,1516,5307,4791,1069,2857,1655,6079,6784,6665,7591,1127,6384,1462,4627,6876,4654,2146,6070,7647,1358,6312,6253,6616,4990,3532,958,3028,511,7352,7649,4966,3065,6781,7470,781,2824,2149,281,4659,5894,730,48,4059,5556,2425,6217,1441,5830,2558,3101,5477,3783,962,7221,2195,5667,7294,4976,4726,888,4804,6435,4986,6219,6358,6114,3974,5146,1964,3669,7552,22,7026,5895,4978,439,1225,5978,3794,4792,971,5995,773,289,6339,280,3369,384,6523,1102,2167,2631,3600,5887,5838,4721,776,4031,6268,1556,7746,2487,6490,313,4344,2216,3920,5666,5922,5253,7460,5583,1934,6611,3317,961,2895,2080,400,642,2071,1535,6111,817,3323,2595,1164,5972,1740,6123,6530,4963,6277,2303,2920,7441,2435,5171,4222,1452,4537,1862,2795,4331,7136,3734,7375,4934,472,5622,5687,1566,4514,2940,2434,2775,3799,7126,4294,2142,210,1729,4305,2217,4516,3679,794,1159,4186,2926,1092,4857,6676,1166,638,6453,3231,4620,3214,1936,855,610,4288,1099,3938,4757,3725,1292,7346,4005,4293,7423,2313,1105,6863,42,5905,4793,343,2291,1394,230,5918,6423,7140,1089,4078,2062,1198,2897,1840,4731,844,6576,158,5057,1455,7597,858,6081,7410,2826,298,6604,2178,6470,4647,2315,4737,5736,5376,1370,1490,3798,5271,2736,7075,5318,810,5829,4133,170,475,7701,3107,2491,7396,1293,2264,1990,5867,3580,6975,3706,1499,5327,6942,372,7033,5483,2652,1274,7030,2428,2403,6907,871,1904,3732,1760,1512,3595,2612,2751,5067,337,848,1923,7556,4788,3559,7202,1777,5092,1014,954,5720,4624,2908,2245,4357,363,927,2476,5796,4741,2183,5343,5518,2604,4740,1388,6012,6151,6637,274,4988,1249,6310,4360,3242,4711,1362,2097,2078,6240,1659,238,5634,2457,178,2357,3727,3977,249,7224,3217,7097,2546,6250,6601,6201,3151,5652,7517,5714,5063,3449,5682,3904,2082,3891,1622,4913,3803,6946,5962,5232,2087,7005,6525,4580,5940,5164,1096,1129,484,4097,3760,5785,6351,692,6938,3039,6564,5994,4742,395,6472,7768,7335,6392,7365,1679,7205,4910,1495,1477,237,6142,4472,1958,295,4552,50,3931,6859,1727,4879,4109,6521,3951,5814,7751,5758,2649,4834,5373,2143,829,6560,6915,499,939,2551,3630,3914,2084,254,6057,6069,2805,4451,7744,4391,5595,3359,3009,1348,6762,3663,3480,5746,2175,1593,294,1612,4734,7341,391,1191,273,3980,6710,204,4146,6733,1360,2767,6562,3984,1919,3723,6871,4839,6163,607,2739,1691,1794,2584,7212,3412,2566,4701,5826,2650,481,5649,5053,2344,1813,5847,795,6735,4590,6411,7081,3988,58,5438,7311,6274,6554,3965,7187,6509,2336,4108,3916,6199,3617,1222,7712,52,3041,7566,5008,1201,2987,5464,3389,7603,4380,3344,3623,3777,6767,2576,2239,5210,6386,2006,2203,6194,5896,2319,5973,3186,6643,566,2221,167,6346,6075,305,187,2096,4662,1781,4844,873,5598,6584,838,606,4010,7151,5573,6903,5247,4483,7534,2730,4544,4235,3268,7278,5382,6403,4173,1270,6200,5169,185,1398,5623,7745,4269,3291,5043,5889,5873,6093,2477,2424,543,1997,2921,1700,2517,2013,3235,6229,1887,719,5304,2450,600,188,5801,5569,3998,5396,2048,4164,6919,581,2847,7497,7208,5165,1371,4358,2371,60,2696,555,6450,3801,1855,2020,1725,4140,3807,5353,1063,4890,1209,3486,271,6877,7494,5671,899,6683,5262,156,1161,7658,3293,2596,3824,3007,5025,4353,3473,3342,5167,6368,31,1321,1253,1567,3632,7674,3625,411,1003,4364,4733,115,3606,5883,3026,6620,4908,4228,383,2229,5904,1258,3675,602,637,3395,4697,926,7049,4052,7642,6951,5525,2016,2233,3493,5196,4416,1316,1663,3180,7012,5981,2822,4548,1464,4386,2861,6950,662,5420,1966,7067,973,1471,4587,437,5882,595,4807,5668,572,6916,702,2088,4084,4438,346,6542,1214,1158,674,2059,969,3774,2202,6362,7225,853,2345,213,217,5251,5260,6366,6189,4145,4230,516,5726,3504,6104,306,6071,1354,703,5066,1914,1872,356,1557,7135,2671,6476,6854,4471,2829,847,2445,3448,3901,2308,3058,1996,5776,4119,5991,2653,6347,4350,4390,3761,1236,2641,897,1747,2125,2466,673,2181,3127,1195,4389,488,7752,3313,4313,6809,1405,4617,793,632,1553,4872,5930,4403,6058,6848,1062,3340,7287,7362,6776,2598,4999,923,5083,866,4606,2744,734,7389,4043,6088,157,1577,1751,6455,1107,707,1473,6016,5435,7319,7174,1947,6488,299,270,7601,6904,2024,1988,6549,7322,7001,3133,520,3362,1572,2471,4332,6405,4325,3077,3542,6264,1886,3249,3501,4610,442,1038,2677,2720,6098,6246,2800,6468,1816,6137,3830,2367,5693,647,338,5755,864,3551,6387,3604,5239,5805,5010,4750,235,7295,5241,2256,6650,1563,5495,3422,3810,5819,3292,2399,1594,1507,3638,5071,5708,1318,5126,2742,2079,6048,2227,1922,4478,4801,3373,6512,903,4894,95,2523,5964,1232,1910,4519,2707,5086,146,5183,2900,4853,6213,3483,6730,1896,358,2889,7448,2752,3088,557,4486,1208,4863,307,2129,4858,4340,7080,4500,2700,1680,5223,1350,1827,5881,4421,2814,5551,6911,1631,1965,3212,5459,3139,7446,118,3227,5348,2130,199,711,4468,3463,7595,4811,3221,4368,536,2502,3427,2522,2918,5370,6391,4300,3352,3976,5715,1749,1126,6126,4996,7573,4512,7261,552,4308,5273,7602,228,5754,3090,6622,5818,4125,6679,1912,6449,1042,2776,7726,441,4670,3145,6971,7480,3215,351,6778,2215,3506,427,6054,5751,6655,3346,2859,137,155,7468,4475,908,2148,5631,5026,5766,366,4197,174,2590,6837,2771,3771,3684,2451,6129,6519,1665,3647,4591,3945,3250,6504,1693,6056,2639,3176,7661,3072,2783,3577,892,2625,1602,3251,4786,6638,4369,2440,609,3247,5202,2225,5632,5980,5985,3841,2254,7526,3243,4619,6072,878,6244,3010,2755,1624,792,7695,2180,163,2842,6539,181,1889,453,3619,6958,1639,1779,5014,266,6961,5238,124,3852,3772,2793,6517,350,1581,7584,3136,457,6042,3015,7118,7550,2825,4082,5015,7617,2524,6573,2562,2236,7426,1960,432,5375,4100,2272,5512,4878,4405,5168,1085,6555,3194,3940,2719,5031,7289,6932,1401,911,1138,1998,6377,2301,4238,110,1294,779,6985,463,3642,6872,6260,7390,7153,5280,2214,6451,4531,1810,2715,6006,727,3655,6125,5256,7669,5584,7121,896,3550,1485,493,6846,3365,3283,7244,2843,3621,544,5816,620,1309,6352,4477,5621,7580,3229,987,1597,4864,2692,2332,4501,785,5385,5603,4713,483,4183,3683,1979,498,677,6984,5184,840,4004,5763,5729,868,6577,6032,1325,2255,5045,192,6900,1257,6402,1689,5717,990,764,7559,4392,7567,1759,1891,7343,5501,4618,1132,6356,1050,6269,4499,5541,2557,2647,3447,262,1087,6851,7366,1798,4185,2407,3959,5442,983,6447,277,7339,2747,5344,634,1981,3671,6121,7018,1175,2684,3909,3785,7228,5070,6247,2348,2683,2597,1830,1190,5710,5942,4006,3092,947,1796,6596,7229,6448,3876,1921,4061,193,3216,687,3780,2119,2176,1917,6372,1959,5917,6171,5643,1994,6429,5048,7373,3843,2766,4336,4257,3690,2373,6168,6167,7246,1890,6376,6135,2185,2449,6682,121,2765,3668,6906,6998,3196,2585,4535,3825,6395,5572,1333,3276,4371,4593,7635,2061,1329,1715,4349,4051,6777,6844,468,4442,1033,1330,2003,1008,2294,937,5277,3264,2846,3484,2134,7466,206,12,666,3219,1114,2664,5602,3712,5286,3048,2732,585,1970,6357,6798,4289,1415,3649,5077,4208,1101,915,7432,1286,5469,5770,2241,3296,5244,6736,5212,2503,6295,3535,1469,2985,6996,3696,1539,3953,7538,4244,6043,2737,6280,6394,6551,6308,7227,473,3168,3429,5762,147,6480,5909,2772,6738,5456,6552,959,613,5786,5379,1973,5249,4588,4685,1171,2057,7412,789,3934,4837,3867,617,5648,6452,1500,103,6050,7713,3593,5127,3302,5104,560,5054,6143,4314,5007,6419,7014,4919,5209,6022,1254,1187,7529,4545,1800,3952,2054,4505,6651,2989,6417,323,7723,5503,3210,3919,2757,102,4049,1666,5853,127,5377,6345,26,4361,1888,6007,1585,2828,4203,5044,2081,2464,577,3438,7197,6321,2000,3814,6727,322,172,4589,7093,2982,3851,2745,3135,6667,1644,7047,4029,4623,5124,774,440,4419,3458,292,5479,5105,7338,4290,54,7072,3236,4719,4526,4255,1873,7177,3602,7268,4496,285,6413,3160,5617,2663,5335,1849,782,5011,4622,5675,1016,6631,3514,6389,135,7715,2136,1719,412,5393,7084,1037,5285,4429,3660,6256,3869,3963,4930,4275,1430,5058,538,2548,3036,6031,4955,6341,1789,2177,1863,4998,2326,6826,4799,1780,2702,494,2284,5529,286,3564,5911,276,6743,1711,3947,2545,4459,7476,2205,3027,312,3819,1883,6329,2201,523,1215,2382,3877,352,1365,750,4725,6935,1197,1331,2064,4395,7425,399,2238,3657,3091,7562,2967,2116,4827,7428,3846,7065,2474,605,5993,4927,6401,7234,3797,3255,1841,884,1439,4708,2184,3670,6038,4262,3301,1804,165,5397,1185,4099,1183,5258,6715,3528,7418,1343,5690,4378,3749,6292,6626,963,1307,5153,4504,6443,7027,4652,1306,4706,6752,3527,1543,7305,7107,5614,6987,4562,25,1773,5900,6291,4664,1347,3424,1755,93,3579,189,6055,584,3019,5174,1838,5107,4784,3361,1943,3662,4151,4903,7201,106,3926,5974,509,5372,422,1068,4013,1875,2343,2511,2017,3190,2107,831,3583,770,7732,7653,7181,2354,2646,2101,5123,7191,4671,6086,7754,5890,5856,7381,1978,7568,2526,6757,2410,4117,6885,6878,5970,6235,78,7313,3460,696,2807,1244,2278,1525,1428,1284,3156,5752,1317,2958,1596,49,5750,561,1505,5473,6644,1283,865,209,3730,4629,7061,4722,3173,3997,7064,4805,5594,1435,1458,2370,6028,4144,6840,4139,3416,4542,6374,6332,1363,5125,182,6979,6407,4461,1335,6989,7459,3656,4060,1402,3821,4911,7696,6430,1018,1021,202,6756,2634,6572,173,7736,4441,1421,1168,4582,909,1903,7070,3533,2467,7263,7163,588,6706,4259,3834,2866,1824,6723,5848,7747,3199,7717,7242,6283,3479,5128,1900,4546,7332,901,4907,6782,7374,7496,2292,6808,3057,6254,6855,972,751,4873,6100,1178,3394,4869,635,1701,5851,344,3735,6700,3838,1131,5296,676,4383,6478,788,4703,2430,6558,6278,3523,7042,7478,3709,7388,6002,3943,501,2972,5957,1109,3089,1972,1145,3721,7167,7574,5312,44,6879,846,4699,4174,1447,2975,7482,5680,6380,4121,4131,3129,1788,448,6154,3056,6383,2815,7329,912,7230,7008,3818,3034,2849,4626,97,4058,5546,2708,6834,5861,6248,3795,4732,6145,6669,7709,4813,6629,3646,2675,5112,2531,5032,7593,1754,3571,2426,4330,6586,2636,4176,6436,2741,2334,4836,1367,724,5580,6754,5800,2138,3253,5024,1059,6734,524,7757,2769,675,3548,7499,83,5674,1146,6905,4028,1522,7219,4810,4547,40,1375,1541,478,86,735,1113,3240,1448,5999,4162,2022,3069,1379,3768,7737,4848,936,2810,1866,5399,1,2102,2306,5150,3574,53,2182,4319,5912,5837,1468,4014,3701,1941,2777,3298,541,1971,7333,7484,1301,7185,2501,2629,2962,5645,1150,3490,1081,6293,5360,4905,7677,5233,5961,2724,5137,5505,3597,814,5825,1618,6569,3652,1026,4356,803,3744,6931,4663,7055,5476,5723,5030,3357,1453,3232,790,3141,3119,4011,5266,3332,2350,3711,4968,4202,2581,6487,4167,5852,4036,2472,7433,3710,3970,382,3733,4495,5824,4179,563,3310,587,87,1991,4209,4283,1546,1942,1984,2123,6297,101,2952,5181,2919,559,3267,6947,6795,1902,7023,7247,1417,99,6920,5582,4806,7610,4575,586,545,5577,3154,5696,4215,3678,7349,232,3396,7604,1204,982,2505,6073,4093,149,2853,1647,7243,464,6732,2385,5532,7086,4032,2246,500,3005,2571,2263,398,7348,6581,651,1626,2785,4277,7372,145,2792,7207,784,1334,1399,1608,5069,62,4763,4560,2845,657,7582,6850,1683,263,4901,3537,7089,5172,94,7488,35,451,6398,3828,2901,1251,985,5721,371,1616,6196,4829,7692,7577,3842,4141,345,808,2875,6486,6223,5943,495,2555,4271,3607,7173,2153,4114,1238,4000,7513,6000,2928,2174,57,1698,4743,6203,2977,508,1848,618,3847,4985,599,5932,1295,2212,4435,3158,721,6422,7631,317,6901,5289,1575,3078,6415,769,7606,7570,7222,4166,7370,5854,7277,3831,4598,623,2147,5407,3304,3808,822,5764,4929,6062,6739,3534,7108,2365,7621,6181,5540,4372,6251,6704,5910,56,4980,4715,3840,1122,2909,81,5303,2463,368,6270,1662,1115,2912,407,3687,1632,527,314,2910,5653,2852,2694,2770,2986,2938,2618,6725,3222,4282,5633,283,851,2056,6314,5813,5650,4794,5309,1112,5862,3451,1802,4672,7032,3562,4592,1946,1758,630,1882,1220,1013,6661,6101,4577,2929,6497,1174,6887,731,1151,2406,759,2728,3012,6080,2379,3280,1047,3689,3465,3113,2670,2891,2567,46,2226,6288,3022,3075,4376,6178,907,1874,1642,4241,4324,3343,2856,3452,2955,3445,428,5449,7132,5094,38,4260,744,316,1377,948,5863,5902,5255,1041,297,7206,6475,2610,4887,3408,2293,7273,2045,1532,6773,1288,6992,1609,2248,3615,3759,2781,4281,624,4892,191,1937,6311,6112,5761,3197,84,1419,1560,5697,5725,614,1155,2802,4250,6495,5110,5173,4665,476,3874,4729,720,6536,381,3855,4182],"read":11238,"next":"552a164f"}, + {"name":"6 words of 12","size":12,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 12"},"indices":[4,11,8,9,7,5],"read":14,"next":"077eddf3"}, + {"name":"6 words of 13","size":13,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 13"},"indices":[5,6,4,3,2,11],"read":11,"next":"83aec74e"}, + {"name":"6 words of 16","size":16,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 16"},"indices":[11,3,10,15,7,8],"read":8,"next":"c189b683"}, + {"name":"6 words of 17","size":17,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 17"},"indices":[9,5,3,11,12,7],"read":9,"next":"b82b7743"}, + {"name":"6 words of 100","size":100,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 100"},"indices":[77,18,41,48,58,60],"read":8,"next":"976596b8"}, + {"name":"6 words of 255","size":255,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 255"},"indices":[179,162,55,253,133,126],"read":6,"next":"6c621f75"}, + {"name":"6 words of 256","size":256,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 256"},"indices":[42,59,184,44,21,16],"read":6,"next":"caa45192"}, + {"name":"6 words of 257","size":257,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 257"},"indices":[135,210,242,65,154,160],"read":26,"next":"c8778946"}, + {"name":"6 words of 2047","size":2047,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 2047"},"indices":[1427,667,604,2042,1632,1698],"read":12,"next":"12f5bd68"}, + {"name":"6 words of 2048","size":2048,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 2048"},"indices":[717,1383,705,229,1916,1660],"read":12,"next":"514e0658"}, + {"name":"6 words of 2049","size":2049,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 2049"},"indices":[1896,604,1955,1437,373,563],"read":16,"next":"1f552afe"}, + {"name":"6 words of 4096","size":4096,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 4096"},"indices":[3366,329,259,1101,997,1552],"read":12,"next":"ba4a07de"}, + {"name":"6 words of 7775","size":7775,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 7775"},"indices":[1556,5053,533,6292,2396,3983],"read":14,"next":"6d6f2e06"}, + {"name":"6 words of 7776","size":7776,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 7776"},"indices":[1522,1052,5366,4760,6603,6405],"read":14,"next":"1e028f83"}, + {"name":"6 words of 7777","size":7777,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 7777"},"indices":[4697,2832,2324,6110,1441,1088],"read":12,"next":"debd0218"}, + {"name":"6 words of 8192","size":8192,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 8192"},"indices":[5622,6365,2307,4380,6765,5885],"read":12,"next":"ed1fc6e1"}, + {"name":"6 words of 65535","size":65535,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 65535"},"indices":[52053,57393,60069,33726,7248,37022],"read":12,"next":"dfc89fd4"}, + {"name":"6 words of 65536","size":65536,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 65536"},"indices":[14606,12671,30058,2426,45855,20473],"read":12,"next":"dc5fb7c7"}, + {"name":"6 words of 65537","size":65537,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 65537"},"indices":[56692,4788,29478,53493,26980,44196],"read":36,"next":"26cd818c"}, + {"name":"6 words of 100000","size":100000,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 100000"},"indices":[69115,76031,73262,26566,2709,63951],"read":30,"next":"316abb7d"}, + {"name":"6 words of 1048577","size":1048577,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 1048577"},"indices":[900768,122124,269913,466370,711218,306573],"read":33,"next":"75d20cfa"}, + {"name":"12 words of 65537, SHA-256 counter blocks","size":65537,"n":12,"stream":{"kind":"counter","seed":"wordkey.Generate counter 65537"},"indices":[21932,33428,8290,57085,9183,17569,28618,21194,47511,49332,51193,58044],"read":66,"next":"2d2caf93"}, + {"name":"6 words of 12, the most","size":12,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 12 most"},"indices":[11,8,10,1,5,9],"read":13,"next":"191eb7eb"}, + {"name":"6 words of 13, the most","size":13,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 13 most"},"indices":[2,7,5,9,3,10],"read":10,"next":"2b27aedd"}, + {"name":"8 words of 17, the most","size":17,"n":8,"stream":{"kind":"seeded","seed":"wordkey.Generate 17 most"},"indices":[16,9,5,1,3,10,0,6],"read":14,"next":"9ddad546"}, + {"name":"50 words of 100, the most","size":100,"n":50,"stream":{"kind":"seeded","seed":"wordkey.Generate 100 most"},"indices":[51,40,75,85,11,44,62,23,8,92,0,34,55,89,31,94,39,60,18,45,74,27,98,57,69,12,1,54,59,20,67,4,7,10,41,52,9,38,63,19,32,68,16,17,43,28,33,21,99,24],"read":87,"next":"ff21a83a"}, + {"name":"the seed of TestGenerate: two indices only, then EOF","list":"es","size":7776,"n":6,"stream":{"kind":"bytes","hex":"0701c821","repeat":64},"read":256,"error":"wordkey: EOF"}, + {"name":"twelve bytes, six indices","list":"es","size":7776,"n":6,"stream":{"kind":"bytes","hex":"000000010002000300040005","repeat":1},"indices":[0,1,2,3,4,5],"words":["abad","abad\u00eda","abandonar","abandono","abanico","abarca"],"read":12}, + {"name":"8191 and 8032 drawn again, 0 drawn twice, 7775 the last index","list":"es","size":7776,"n":6,"stream":{"kind":"bytes","hex":"1fff00001f601e5f00000001000200030004","repeat":1},"indices":[0,7775,1,2,3,4],"words":["abad","\u00fatil","abad\u00eda","abandonar","abandono","abanico"],"read":18}, + {"name":"the three bits above the 13 of 7775 are cleared","list":"es","size":7776,"n":6,"stream":{"kind":"bytes","hex":"e000ffff21002200230024002500","repeat":1},"indices":[0,256,512,768,1024,1280],"words":["abad","alba\u00f1il","ap\u00e9ndice","azufre","bot\u00f3n","capitolio"],"read":14}, + {"name":"the bytes end inside a draw","list":"es","size":7776,"n":6,"stream":{"kind":"bytes","hex":"0000000100","repeat":1},"read":5,"error":"wordkey: unexpected EOF"}, + {"name":"no bytes","list":"es","size":7776,"n":6,"stream":{"kind":"bytes"},"read":0,"error":"wordkey: EOF"}, + {"name":"5 words of the Spanish list","list":"es","size":7776,"n":5,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: a key of words needs at least 6 words, not 5"}, + {"name":"0 words of the Spanish list","list":"es","size":7776,"n":0,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: a key of words needs at least 6 words, not 0"}, + {"name":"-1 words of the Spanish list","list":"es","size":7776,"n":-1,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: a key of words needs at least 6 words, not -1"}, + {"name":"3889 words of the Spanish list","list":"es","size":7776,"n":3889,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: 3889 words of a list of 7776"}, + {"name":"7776 words of the Spanish list","list":"es","size":7776,"n":7776,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: 7776 words of a list of 7776"}, + {"name":"6 words of 11","size":11,"n":6,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: 6 words of a list of 11"}, + {"name":"6 words of 0","size":0,"n":6,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: 6 words of a list of 0"}, + {"name":"5 words of 0","size":0,"n":5,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: a key of words needs at least 6 words, not 5"}, + {"name":"7 words of 12","size":12,"n":7,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: 7 words of a list of 12"}, + {"name":"7 words of 13","size":13,"n":7,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: 7 words of a list of 13"} + ], + "bits": [ + {"size":1,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":1,"count":1,"bits":"0","hex":"0000000000000000"}, + {"size":1,"count":2,"bits":"-Inf","hex":"fff0000000000000"}, + {"size":1,"count":6,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":1,"count":7,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":1,"count":8,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":1,"count":12,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":2,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":2,"count":1,"bits":"1","hex":"3ff0000000000000"}, + {"size":2,"count":2,"bits":"1","hex":"3ff0000000000000"}, + {"size":2,"count":6,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":2,"count":7,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":2,"count":8,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":2,"count":12,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":3,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":3,"count":1,"bits":"1.5849625007211563","hex":"3ff95c01a39fbd69"}, + {"size":3,"count":2,"bits":"2.584962500721156","hex":"4004ae00d1cfdeb4"}, + {"size":3,"count":6,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":3,"count":7,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":3,"count":8,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":3,"count":12,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":5,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":5,"count":1,"bits":"2.321928094887362","hex":"4002934f0979a371"}, + {"size":5,"count":2,"bits":"4.321928094887362","hex":"401149a784bcd1b8"}, + {"size":5,"count":6,"bits":"-Inf","hex":"fff0000000000000"}, + {"size":5,"count":7,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":5,"count":8,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":5,"count":12,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":12,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":12,"count":1,"bits":"3.584962500721156","hex":"400cae00d1cfdeb4"}, + {"size":12,"count":2,"bits":"7.044394119358453","hex":"401c2d75a6eb1dfb"}, + {"size":12,"count":6,"bits":"19.343602137745734","hex":"403357f64f487420"}, + {"size":12,"count":7,"bits":"21.928564638466888","hex":"4035edb669826ff6"}, + {"size":12,"count":8,"bits":"24.25049273335425","hex":"403840204ab1a464"}, + {"size":12,"count":12,"bits":"28.835455234075408","hex":"403cd5e064eba03b"}, + {"size":13,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":13,"count":1,"bits":"3.700439718141092","hex":"400d9a802391e233"}, + {"size":13,"count":2,"bits":"7.285402218862249","hex":"401d24407ab0e074"}, + {"size":13,"count":6,"bits":"20.23668693382922","hex":"40343c9783d02fe0"}, + {"size":13,"count":7,"bits":"23.044041855886825","hex":"40370b4653bab066"}, + {"size":13,"count":8,"bits":"25.62900435660798","hex":"4039a1066df4ac3c"}, + {"size":13,"count":12,"bits":"32.535894952216495","hex":"4040449834aeee40"}, + {"size":100,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":100,"count":1,"bits":"6.643856189774724","hex":"401a934f0979a371"}, + {"size":100,"count":2,"bits":"13.273212809854334","hex":"402a8be28ca65863"}, + {"size":100,"count":6,"bits":"39.64265360520877","hex":"4043d242792c839b"}, + {"size":100,"count":7,"bits":"46.19724245688641","hex":"4047193f3da6dadb"}, + {"size":100,"count":8,"bits":"52.73640126799444","hex":"404a5e4265916270"}, + {"size":100,"count":12,"bits":"78.73534439154622","hex":"4053af0fe1ec3f3c"}, + {"size":255,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":255,"count":1,"bits":"7.994353436858858","hex":"401ffa37c98fe55f"}, + {"size":255,"count":2,"bits":"15.983038123631022","hex":"402ff750c5df6ed2"}, + {"size":255,"count":6,"bits":"47.880639460438104","hex":"4047f0b8cb39130a"}, + {"size":255,"count":7,"bits":"55.840641392506186","hex":"404beb9a231c3d2e"}, + {"size":255,"count":8,"bits":"63.79483770289306","hex":"404fe5bd3de9c6d8"}, + {"size":255,"count":12,"bits":"95.55309471638243","hex":"4057e365e7619cfd"}, + {"size":256,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":256,"count":1,"bits":"8","hex":"4020000000000000"}, + {"size":256,"count":2,"bits":"15.994353436858859","hex":"402ffd1be4c7f2b0"}, + {"size":256,"count":6,"bits":"47.914855175776026","hex":"4047f519f9724466"}, + {"size":256,"count":7,"bits":"55.88063946043811","hex":"404bf0b8cb39130b"}, + {"size":256,"count":8,"bits":"63.84064139250619","hex":"404feb9a231c3d2f"}, + {"size":256,"count":12,"bits":"95.62235737881954","hex":"4057e7d4b40b1d12"}, + {"size":257,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":257,"count":1,"bits":"8.005624549193879","hex":"402002e1388daf56"}, + {"size":257,"count":2,"bits":"16.00562454919388","hex":"403001709c46d7ab"}, + {"size":257,"count":6,"bits":"47.94893617101913","hex":"4047f976bd8e4262"}, + {"size":257,"count":7,"bits":"55.9204797249699","hex":"404bf5d24795b03b"}, + {"size":257,"count":8,"bits":"63.88626400963199","hex":"404ff171195c7ee0"}, + {"size":257,"count":12,"bits":"95.69134398901087","hex":"4057ec3efadbc5a0"}, + {"size":2047,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":2047,"count":1,"bits":"10.99929538702341","hex":"4025ffa3a51c9e51"}, + {"size":2047,"count":2,"bits":"21.99788581676874","hex":"4035ff7571e429fb"}, + {"size":2047,"count":6,"bits":"65.9851910651465","hex":"40507f0d5ed34766"}, + {"size":2047,"count":7,"bits":"76.98025153217921","hex":"40533ebc70ec2412"}, + {"size":2047,"count":8,"bits":"87.97460496903807","hex":"4055fe5fed852268"}, + {"size":2047,"count":12,"bits":"131.94494147626207","hex":"40607e3cf5e825bf"}, + {"size":2048,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":2048,"count":1,"bits":"11","hex":"4026000000000000"}, + {"size":2048,"count":2,"bits":"21.99929538702341","hex":"4035ffd1d28e4f28"}, + {"size":2048,"count":6,"bits":"65.9894239142687","hex":"40507f52b8ae6a85"}, + {"size":2048,"count":7,"bits":"76.9851910651465","hex":"40533f0d5ed34766"}, + {"size":2048,"count":8,"bits":"87.98025153217921","hex":"4055febc70ec2412"}, + {"size":2048,"count":12,"bits":"131.95341963018637","hex":"40607e8269e2607a"}, + {"size":2049,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":2049,"count":1,"bits":"11.000704269011246","hex":"4026005c4f58bde5"}, + {"size":2049,"count":2,"bits":"22.000704269011244","hex":"4036002e27ac5ef2"}, + {"size":2049,"count":6,"bits":"65.9936546945467","hex":"40507f9809dc2614"}, + {"size":2049,"count":7,"bits":"76.99012818327994","hex":"40533f5e42998241"}, + {"size":2049,"count":8,"bits":"87.98589533415773","hex":"4055ff18e8be5f22"}, + {"size":2049,"count":12,"bits":"131.96189363423173","hex":"40607ec7d528a830"}, + {"size":4096,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":4096,"count":1,"bits":"12","hex":"4028000000000000"}, + {"size":4096,"count":2,"bits":"23.99964773652837","hex":"4037ffe8e9ffe8e7"}, + {"size":4096,"count":6,"bits":"71.99471432662824","hex":"4051ffa966476ec8"}, + {"size":4096,"count":7,"bits":"83.99259945445735","hex":"4054ff86bfdcbafe"}, + {"size":4096,"count":8,"bits":"95.99013180198372","hex":"4057ff5e51c70ffa"}, + {"size":4096,"count":12,"bits":"143.97673166270826","hex":"4061ff4162c28997"}, + {"size":7775,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":7775,"count":1,"bits":"12.924626959905327","hex":"4029d968b4739629"}, + {"size":7775,"count":2,"bits":"25.849068352244522","hex":"4039d95c8b24f576"}, + {"size":7775,"count":6,"bits":"77.54497776841153","hex":"405362e0ea6f17f9"}, + {"size":7775,"count":7,"bits":"90.46849096471993","hex":"40569dfbc186fc64"}, + {"size":7775,"count":8,"bits":"103.39181845013913","hex":"4059d9138db15449"}, + {"size":7775,"count":12,"bits":"155.0832708046572","hex":"406362aa2788d6db"}, + {"size":7776,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":7776,"count":1,"bits":"12.92481250360578","hex":"4029d9810643d661"}, + {"size":7776,"count":2,"bits":"25.849439463511107","hex":"4039d974dd5bb645"}, + {"size":7776,"count":6,"bits":"77.54609138872225","hex":"405362f3294bcc1d"}, + {"size":7776,"count":7,"bits":"90.46979027201732","hex":"40569e110b3792c6"}, + {"size":7776,"count":8,"bits":"103.39330346832573","hex":"4059d92be24f7731"}, + {"size":7776,"count":12,"bits":"155.08549890554931","hex":"406362bc683365b3"}, + {"size":7777,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":7777,"count":1,"bits":"12.924998023446696","hex":"4029d999574722eb"}, + {"size":7777,"count":2,"bits":"25.849810527052476","hex":"4039d98d2ec57ca6"}, + {"size":7777,"count":6,"bits":"77.5472048657836","hex":"40536305678eb02b"}, + {"size":7777,"count":7,"bits":"90.47108941216894","hex":"40569e265434b07a"}, + {"size":7777,"count":8,"bits":"103.39478829546401","hex":"4059d94436207723"}, + {"size":7777,"count":12,"bits":"155.08772671972133","hex":"406362cea8440608"}, + {"size":8192,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":8192,"count":1,"bits":"13","hex":"402a000000000000"}, + {"size":8192,"count":2,"bits":"25.999823879015725","hex":"4039fff4752e21e5"}, + {"size":8192,"count":6,"bits":"77.99735775509549","hex":"40537fd4b59f2304"}, + {"size":8192,"count":7,"bits":"90.99630070653858","hex":"4056bfc36409e427"}, + {"size":8192,"count":8,"bits":"103.9950674079001","hex":"4059ffaf2f358fc5"}, + {"size":8192,"count":12,"bits":"155.98837128175916","hex":"40637fa0bccf6ec2"}, + {"size":10000,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":10000,"count":1,"bits":"13.287712379549449","hex":"402a934f0979a371"}, + {"size":10000,"count":2,"bits":"26.575280482380855","hex":"403a934594e9da56"}, + {"size":10000,"count":6,"bits":"79.72410983788599","hex":"4053ee57d0ca1ba9"}, + {"size":10000,"count":7,"bits":"93.01095634062187","hex":"405740b3823929e8"}, + {"size":10000,"count":8,"bits":"106.29765848001738","hex":"405a930cd627434f"}, + {"size":10000,"count":12,"bits":"159.4430231152088","hex":"4063ee2d3ecfe634"}, + {"size":65535,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":65535,"count":1,"bits":"15.999977986052736","hex":"402ffffd1d55a205"}, + {"size":65535,"count":2,"bits":"31.999933957822293","hex":"403ffffbabff01b0"}, + {"size":65535,"count":6,"bits":"95.99953769535011","hex":"4057fff86cf42978"}, + {"size":65535,"count":7,"bits":"111.99938359066472","hex":"405bfff5e6978419"}, + {"size":65535,"count":8,"bits":"127.99920746968044","hex":"405ffff303e30c92"}, + {"size":65535,"count":12,"bits":"191.9982828160347","hex":"4067fff1eecde0e4"}, + {"size":65536,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":65536,"count":1,"bits":"16","hex":"4030000000000000"}, + {"size":65536,"count":2,"bits":"31.999977986052734","hex":"403ffffe8eaad102"}, + {"size":65536,"count":6,"bits":"95.99966978407262","hex":"4057fffa96f9590b"}, + {"size":65536,"count":7,"bits":"111.99953769535013","hex":"405bfff86cf42979"}, + {"size":65536,"count":8,"bits":"127.99938359066473","hex":"405ffff5e697841a"}, + {"size":65536,"count":12,"bits":"191.9985470055745","hex":"4067fff418d98ec2"}, + {"size":65537,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":65537,"count":1,"bits":"16.00002201361136","hex":"403000017153bda9"}, + {"size":65537,"count":2,"bits":"32.00002201361136","hex":"40400000b8a9ded4"}, + {"size":65537,"count":6,"bits":"95.99980187077954","hex":"4057fffcc0fc5e93"}, + {"size":65537,"count":7,"bits":"111.99969179768398","hex":"405bfffaf34e4875"}, + {"size":65537,"count":8,"bits":"127.99955970896148","hex":"405ffff8c94918e3"}, + {"size":65537,"count":12,"bits":"191.9988111910827","hex":"4067fff642e31287"}, + {"size":1048576,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":1048576,"count":1,"bits":"20","hex":"4034000000000000"}, + {"size":1048576,"count":2,"bits":"39.99999862413814","hex":"4043fffff4755bf1"}, + {"size":1048576,"count":6,"bits":"119.99997936204582","hex":"405dffffa9702a5a"}, + {"size":1048576,"count":7,"bits":"139.99997110685496","hex":"40617fffc3681c62"}, + {"size":1048576,"count":8,"bits":"159.99996147579435","hex":"4063ffffaf35797e"}, + {"size":1048576,"count":12,"bits":"239.99990919282837","hex":"406dffff4190455d"}, + {"size":2147483647,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":2147483647,"count":1,"bits":"30.999999999328193","hex":"403efffffffd1d57"}, + {"size":2147483647,"count":2,"bits":"61.999999997984574","hex":"404efffffffbac02"}, + {"size":2147483647,"count":6,"bits":"185.99999998589203","hex":"40673ffffff86d04"}, + {"size":2147483647,"count":7,"bits":"216.99999998118938","hex":"406b1ffffff5e6b0"}, + {"size":2147483647,"count":8,"bits":"247.99999997581492","hex":"406efffffff30407"}, + {"size":2147483647,"count":12,"bits":"371.99999994759895","hex":"40773ffffff1ef07"}, + {"size":2147483648,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":2147483648,"count":1,"bits":"31","hex":"403f000000000000"}, + {"size":2147483648,"count":2,"bits":"61.999999999328196","hex":"404efffffffe8eac"}, + {"size":2147483648,"count":6,"bits":"185.99999998992288","hex":"40673ffffffa9703"}, + {"size":2147483648,"count":7,"bits":"216.99999998589203","hex":"406b1ffffff86d04"}, + {"size":2147483648,"count":8,"bits":"247.99999998118938","hex":"406efffffff5e6b0"}, + {"size":2147483648,"count":12,"bits":"371.9999999556607","hex":"40773ffffff41907"}, + {"size":4294967295,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":4294967295,"count":1,"bits":"31.999999999664098","hex":"403ffffffffe8eac"}, + {"size":4294967295,"count":2,"bits":"63.999999998992294","hex":"404ffffffffdd602"}, + {"size":4294967295,"count":6,"bits":"191.99999999294604","hex":"4067fffffffc3683"}, + {"size":4294967295,"count":7,"bits":"223.99999999059472","hex":"406bfffffffaf359"}, + {"size":4294967295,"count":8,"bits":"255.99999998790747","hex":"406ffffffff98204"}, + {"size":4294967295,"count":12,"bits":"383.9999999737995","hex":"4077fffffff8f784"}, + {"size":4294967296,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":4294967296,"count":1,"bits":"32","hex":"4040000000000000"}, + {"size":4294967296,"count":2,"bits":"63.9999999996641","hex":"404fffffffff4756"}, + {"size":4294967296,"count":6,"bits":"191.99999999496146","hex":"4067fffffffd4b82"}, + {"size":4294967296,"count":7,"bits":"223.99999999294604","hex":"406bfffffffc3683"}, + {"size":4294967296,"count":8,"bits":"255.99999999059472","hex":"406ffffffffaf359"}, + {"size":4294967296,"count":12,"bits":"383.9999999778303","hex":"4077fffffffa0c83"}, + {"size":4294967297,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":4294967297,"count":1,"bits":"32.0000000003359","hex":"404000000000b8aa"}, + {"size":4294967297,"count":2,"bits":"64.0000000003359","hex":"4050000000005c55"}, + {"size":4294967297,"count":6,"bits":"191.99999999697687","hex":"4067fffffffe6081"}, + {"size":4294967297,"count":7,"bits":"223.99999999529734","hex":"406bfffffffd79ac"}, + {"size":4294967297,"count":8,"bits":"255.99999999328193","hex":"406ffffffffc64ad"}, + {"size":4294967297,"count":12,"bits":"383.9999999818612","hex":"4077fffffffb2183"}, + {"size":4503599627370497,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":4503599627370497,"count":1,"bits":"52","hex":"404a000000000000"}, + {"size":4503599627370497,"count":2,"bits":"104","hex":"405a000000000000"}, + {"size":4503599627370497,"count":6,"bits":"312","hex":"4073800000000000"}, + {"size":4503599627370497,"count":7,"bits":"364","hex":"4076c00000000000"}, + {"size":4503599627370497,"count":8,"bits":"416","hex":"407a000000000000"}, + {"size":4503599627370497,"count":12,"bits":"624","hex":"4083800000000000"}, + {"size":9007199254740991,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":9007199254740991,"count":1,"bits":"53","hex":"404a800000000000"}, + {"size":9007199254740991,"count":2,"bits":"106","hex":"405a800000000000"}, + {"size":9007199254740991,"count":6,"bits":"318","hex":"4073e00000000000"}, + {"size":9007199254740991,"count":7,"bits":"371","hex":"4077300000000000"}, + {"size":9007199254740991,"count":8,"bits":"424","hex":"407a800000000000"}, + {"size":9007199254740991,"count":12,"bits":"636","hex":"4083e00000000000"}, + {"size":9007199254740992,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":9007199254740992,"count":1,"bits":"53","hex":"404a800000000000"}, + {"size":9007199254740992,"count":2,"bits":"106","hex":"405a800000000000"}, + {"size":9007199254740992,"count":6,"bits":"318","hex":"4073e00000000000"}, + {"size":9007199254740992,"count":7,"bits":"371","hex":"4077300000000000"}, + {"size":9007199254740992,"count":8,"bits":"424","hex":"407a800000000000"}, + {"size":9007199254740992,"count":12,"bits":"636","hex":"4083e00000000000"}, + {"size":0,"count":1,"bits":"-Inf","hex":"fff0000000000000"}, + {"size":-1,"count":1,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":7776,"count":-1,"bits":"0","hex":"0000000000000000"}, + {"size":0,"count":0,"bits":"0","hex":"0000000000000000"} + ], + "bits_digests": [ + {"name":"one word of 1 to 65536: the log2 of Go","sizes":[1,65536],"counts":[1,1],"sha256":"54467d69cce12574b891110ee6b74c2e426a833a51ea3df003c7658cfa3ab6de"}, + {"name":"6 to 8 words of 2048 to 10000","sizes":[2048,10000],"counts":[6,8],"sha256":"9e055008813b6d2ec5b9477a777c44d30d650134cd890eeb679552403297332e"}, + {"name":"0 to 600 words of 7776","sizes":[7776,7776],"counts":[0,600],"sha256":"b6e756155be0121f6db294a47b3dbb947652cc931fb078f1db5a9e39643c905a"}, + {"name":"1 word of 2^32 - 4096 to 2^32 + 4096","sizes":[4294963200,4294971392],"counts":[1,1],"sha256":"a95430f39eda0ef2865e11d1b92c8b0e604e4a9387ac881905d77af880240d2d"} + ] +} +'''; diff --git a/test/vectors/wordlist_vectors.json b/test/vectors/wordlist_vectors.json new file mode 100644 index 0000000..12dddf7 --- /dev/null +++ b/test/vectors/wordlist_vectors.json @@ -0,0 +1,787 @@ +{ + "description": "The word lists of package wordkey of the Go reference (generate.go, spec \u00a738.1) for lib/src/wordlist.dart; see tool/wordlist_go_vectors.go. Binary values and words are lower-case hex. The base list is word i = pal and three letters, a + i/676, a + i/26%26 and a + i%26; a case of size n takes its first n words, replaces the word at each at of set, and adds those of append. lists: the SHA-256, bytes and words of each built-in list. parse: the body of List on the text prefix, the base list joined by sep, and suffix (sha256 is that of the text): the words read, and ok or the error. check_list: CheckList, ok or the error (sha256 is that of the words joined by LF). alphabet: CheckList of the base list of 2048 whose first word is pala, a code point and zz, for each code point of the planes but the surrogates: the SHA-256 of the lines U+XXXX result, the code points of the words it accepts, and alphabet_results, each result up to U+017F. generate: Generate on the list of the Spanish words (list es) or on a list of size words whose indices they are, reading a stream: seeded, the keystream of SeededRandomSource of the seed; counter, SHA-256 of the label and a 32-bit big-endian counter from 0, block after block; bytes, hex repeated repeat times, which end. The indices drawn, the bytes read and the next four of an endless stream, or the error. bits: Bits, its shortest decimal and the hex of its float64. bits_digests: the SHA-256 of the 8 big-endian bytes of each Bits of the sizes and counts, inclusive, sizes outer.", + "generator": "tool/wordlist_go_vectors.go, go1.26.8", + "source": "27a75eefcd2ac2a3b32930d6872f3b5b6e648792", + "default_count": 7, + "min_list_size": 2048, + "min_words": 6, + "min_letters": 3, + "alphabet": {"word":"pala, the code point and zz, the first word of the base list of 2048","planes":[0,1,14],"count":194560,"sha256":"9119a1741586b087cc8fdcce99b00931d34c926f5dc54d7fa0ff250402a11ba9","ok":["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","\u00e1","\u00e9","\u00ed","\u00f1","\u00f3","\u00fa","\u00fc"]}, + "lists": [ + {"lang":"es","sha256":"ff77b487765c000da97cca58fe94a2cdb947303e7a07460614d7d95d800034fe","bytes":61843,"words":7776} + ], + "parse": [ + {"name":"2048 words, one per line, with a final LF","lang":"es","size":2048,"prefix":"","sep":"0a","suffix":"0a","sha256":"40e5649349cf1302065f2ceda7e7c4aec69e423fb8916c20b4445b229df6add1","words":2048,"result":"ok"}, + {"name":"without the final LF","lang":"es","size":2048,"prefix":"","sep":"0a","suffix":"","sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","words":2048,"result":"ok"}, + {"name":"7776 words","lang":"es","size":7776,"prefix":"","sep":"0a","suffix":"0a","sha256":"ed7549c5528253a352f8359ddb6cdcd7430536b97de1c42e2e2b20660e1db48c","words":7776,"result":"ok"}, + {"name":"an empty last line: two final LF","lang":"es","size":2048,"prefix":"","sep":"0a","suffix":"0a0a","sha256":"5299dfa91913c2444195faa2c595acd72ad3712d8a9c9b8d1f5cf54c48c175c0","words":0,"result":"wordkey: the list \"es\": line 2049, \"\", is not one word of 3 or more letters"}, + {"name":"an empty first line","lang":"es","size":2048,"prefix":"0a","sep":"0a","suffix":"0a","sha256":"3570e47619facf0aef02f91bb5c7ffb4836896e4793b22a34e6cb9a41e24a4f3","words":0,"result":"wordkey: the list \"es\": line 1, \"\", is not one word of 3 or more letters"}, + {"name":"CR LF lines","lang":"es","size":2048,"prefix":"","sep":"0d0a","suffix":"0d0a","sha256":"5101863512608d6f32553f12c84f0a12e1b211bf5ab2b97e80d62a75b3d104f4","words":0,"result":"wordkey: the list \"es\": line 1, \"palaaa\\r\", holds U+000D, which is not in the alphabet of \"es\""}, + {"name":"CR LF lines, the last without","lang":"es","size":2048,"prefix":"","sep":"0d0a","suffix":"","sha256":"2b7926ee88319902d851db25b98b86f322317cb831b006659bc2b813683e0332","words":0,"result":"wordkey: the list \"es\": line 1, \"palaaa\\r\", holds U+000D, which is not in the alphabet of \"es\""}, + {"name":"CR lines","lang":"es","size":2048,"prefix":"","sep":"0d","suffix":"0d","sha256":"475eae5815dc03f07b0ebb538ac7dcb04b87a10e589f6a9aec4355b896ccf92a","words":0,"result":"wordkey: the list \"es\": 1 words, fewer than 2048"}, + {"name":"a byte order mark","lang":"es","size":2048,"prefix":"efbbbf","sep":"0a","suffix":"0a","sha256":"984ec86238f6eff77e6426203cfddda9068720fc8e1db26c36f9070efce4dbbe","words":0,"result":"wordkey: the list \"es\": line 1: wordkey: the words hold the invisible character U+FEFF"}, + {"name":"an empty text","lang":"es","size":0,"prefix":"","sep":"0a","suffix":"","sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","words":0,"result":"wordkey: the list \"es\": 1 words, fewer than 2048"}, + {"name":"an LF only","lang":"es","size":0,"prefix":"","sep":"0a","suffix":"0a","sha256":"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b","words":0,"result":"wordkey: the list \"es\": 1 words, fewer than 2048"}, + {"name":"2047 words","lang":"es","size":2047,"prefix":"","sep":"0a","suffix":"0a","sha256":"6254d217042f509c1c5d32a4ad3d907b45105a167e75b41b6b5e088ff304fc1e","words":0,"result":"wordkey: the list \"es\": 2047 words, fewer than 2048"}, + {"name":"the words separated by spaces","lang":"es","size":2048,"prefix":"","sep":"20","suffix":"0a","sha256":"10dae8e91c4d951d43dafc1c2a37d32041bf1d1909a15ff9b0bd15244214f4c3","words":0,"result":"wordkey: the list \"es\": 1 words, fewer than 2048"}, + {"name":"a language without an alphabet","lang":"xx","size":2048,"prefix":"","sep":"0a","suffix":"0a","sha256":"40e5649349cf1302065f2ceda7e7c4aec69e423fb8916c20b4445b229df6add1","words":0,"result":"wordkey: the list \"xx\": no alphabet for the language \"xx\""}, + {"name":"a byte that is not valid UTF-8","lang":"es","size":2048,"set":[{"at":6,"word":"70616cff6161"}],"prefix":"","sep":"0a","suffix":"0a","sha256":"31c967816ac079ef582ad79fe4ce76df580e02dade6b6bf1f4e865e7ed333a11","words":0,"result":"wordkey: the list \"es\": line 7, \"pal\\xffaa\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"a sequence cut at the end of the text","lang":"es","size":2048,"set":[{"at":2047,"word":"70616c7a7ac3"}],"prefix":"","sep":"0a","suffix":"","sha256":"2e6660234b4afb4d3a02660f71b8c8b80b7d245d9d5324730a7ba5af90a2064b","words":0,"result":"wordkey: the list \"es\": line 2048, \"palzz\\xc3\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"the same word twice","lang":"es","size":2048,"set":[{"at":2000,"word":"70616c616161"}],"prefix":"","sep":"0a","suffix":"0a","sha256":"9f2acbb0eae1bb8003be8a8721e54a0905d2f776e8c4a2d467a920c4e3141922","words":0,"result":"wordkey: the list \"es\": line 2001, \"palaaa\", is the same word as \"palaaa\" once normalized"}, + {"name":"a capital letter","lang":"es","size":2048,"set":[{"at":100,"word":"50616c647777"}],"prefix":"","sep":"0a","suffix":"0a","sha256":"c145284ea3e147b5527ceb511740a980af3cb53289176da82e08d084d741833d","words":0,"result":"wordkey: the list \"es\": line 101, \"Paldww\", holds U+0050, which is not in the alphabet of \"es\""}, + {"name":"letters of the alphabet","lang":"es","size":2048,"set":[{"at":0,"word":"c3a1c3a9c3adc3b3c3bac3bcc3b1"}],"prefix":"","sep":"0a","suffix":"0a","sha256":"62b5e70acd207e5609c415f64652174b4f29418f39daf4d9a83a89a3aa778e20","words":2048,"result":"ok"} + ], + "check_list": [ + {"name":"the base list","lang":"es","size":2048,"sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","result":"ok"}, + {"name":"a language without an alphabet","lang":"xx","size":2048,"sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","result":"no alphabet for the language \"xx\""}, + {"name":"2047 words","lang":"es","size":2047,"sha256":"006232a478c66e976927c8614ebea20ea657baf0ae52f80ec53c81d57a419957","result":"2047 words, fewer than 2048"}, + {"name":"two words in a line","lang":"es","size":2048,"set":[{"at":5,"word":"646f732070616c6162726173"}],"sha256":"f42912452330cc6b7471acab57b52d26d6d05f81afd5dbea729f579beedeb3de","result":"line 6, \"dos palabras\", is not one word of 3 or more letters"}, + {"name":"two spaces","lang":"es","size":2048,"set":[{"at":5,"word":"2020"}],"sha256":"cc58b1f63c0f95a24c8a9e7c1159ee8f1372243227a09d389f5bb77034fd8088","result":"line 6, \" \", is not one word of 3 or more letters"}, + {"name":"two letters","lang":"es","size":2048,"set":[{"at":5,"word":"6d69"}],"sha256":"9295042e20f0a44e0c567c74aee7c1431406698d0876deaf6c6a9d221dacbe06","result":"line 6, \"mi\", is not one word of 3 or more letters"}, + {"name":"ZWSP","lang":"es","size":2048,"set":[{"at":5,"word":"63617361e2808b"}],"sha256":"e2047d1479f8a0c1bcdc7c432cd51f84b44164fdb6fc550aacd4b67eae868cc7","result":"line 6: wordkey: the words hold the invisible character U+200B"}, + {"name":"a capital","lang":"es","size":2048,"set":[{"at":5,"word":"50616c616166"}],"sha256":"ab2d74b6b1aa4ebc6154e932f1db82e8cbe9eaa8a95c3362c3f77cb577323e95","result":"line 6, \"Palaaf\", holds U+0050, which is not in the alphabet of \"es\""}, + {"name":"a Cyrillic letter that looks like a Latin c","lang":"es","size":2048,"set":[{"at":5,"word":"d181617361"}],"sha256":"0a2eebb54d9a57dad50b557a06eb73fd0bbeb468a5c8bb72705d4c62db11ee38","result":"line 6, \"\u0441asa\", holds U+0441, which is not in the alphabet of \"es\""}, + {"name":"a digit","lang":"es","size":2048,"set":[{"at":5,"word":"70616c31"}],"sha256":"e125536a8e6d771fb734db57ae5cf630583558af2957f0ed42e3b9a50aba7a43","result":"line 6, \"pal1\", holds U+0031, which is not in the alphabet of \"es\""}, + {"name":"the CR of a CR LF line","lang":"es","size":2048,"set":[{"at":5,"word":"70616c6161660d"}],"sha256":"bfbabbff5776d427b31f38898a61d52c0396bc1609baf8ee31828698d35b7e00","result":"line 6, \"palaaf\\r\", holds U+000D, which is not in the alphabet of \"es\""}, + {"name":"the same word","lang":"es","size":2048,"set":[{"at":5,"word":"70616c616165"}],"sha256":"1993a45d3423b863588c5211ca64859d9568fd433cac83d93e3fa6383ada8d55","result":"line 6, \"palaae\", is the same word as \"palaae\" once normalized"}, + {"name":"the same word once normalized","lang":"es","size":2048,"set":[{"at":5,"word":"70616c61c3a165"}],"sha256":"e2abb6dda7cc7f1e7eeb62d25c9e4e910b48265b17643db34a83f82b10b8bd12","result":"line 6, \"pala\u00e1e\", is the same word as \"palaae\" once normalized"}, + {"name":"papa after pap\u00e1","lang":"es","size":2048,"set":[{"at":0,"word":"706170c3a1"}],"append":["70617061"],"sha256":"8feff334849c99f57f0730a53d0b69193d319cc5311ed35fd7c63c1ccd822108","result":"line 2049, \"papa\", is the same word as \"pap\u00e1\" once normalized"}, + {"name":"no words","lang":"es","size":0,"sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","result":"0 words, fewer than 2048"}, + {"name":"no words in a language without an alphabet","lang":"xx","size":0,"sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","result":"no alphabet for the language \"xx\""}, + {"name":"the empty language","lang":"","size":2048,"sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","result":"no alphabet for the language \"\""}, + {"name":"ES, in capitals","lang":"ES","size":2048,"sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","result":"no alphabet for the language \"ES\""}, + {"name":"es and a space","lang":"es ","size":2048,"sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","result":"no alphabet for the language \"es \""}, + {"name":"espa\u00f1ol","lang":"espa\u00f1ol","size":2048,"sha256":"1bd1ad0e0e0bed858ff1c860a08050ae4ca4fc2ab8b264249172cac28005e44f","result":"no alphabet for the language \"espa\u00f1ol\""}, + {"name":"2049 words","lang":"es","size":2049,"sha256":"4a3d02931aa351dbabd89a53ec77ae4008f2e7b1021ff4b3b8d62af0c2f5d486","result":"ok"}, + {"name":"7776 words","lang":"es","size":7776,"sha256":"d143891cbb69ea644de7f2036b93e6fd99040b7bee852aee3a9f21b8147b5fe2","result":"ok"}, + {"name":"17576 words","lang":"es","size":17576,"sha256":"88120b465c3f3fdf5d987f982de3ca66a56225595af185bd242a857843c74777","result":"ok"}, + {"name":"an empty word","lang":"es","size":2048,"set":[{"at":5,"word":""}],"sha256":"639e41bb771d1c353a573e01d40dd1bfb985f01563cf3ff572826ef258f14c50","result":"line 6, \"\", is not one word of 3 or more letters"}, + {"name":"a word of three letters","lang":"es","size":2048,"set":[{"at":5,"word":"70616c"}],"sha256":"78956c5afcfb1abb4844700cb7aae4168b65e7c841177446758e44b44df380dd","result":"ok"}, + {"name":"\u00f1u, two letters","lang":"es","size":2048,"set":[{"at":5,"word":"c3b175"}],"sha256":"8cc44a85f48c935cfb342d979d758e66404d64c56a38387f8b5ecfb07ba4dcaf","result":"line 6, \"\u00f1u\", is not one word of 3 or more letters"}, + {"name":"\u00f1u\u00f1, three letters","lang":"es","size":2048,"set":[{"at":5,"word":"c3b175c3b1"}],"sha256":"dc2601fdba7c90d378652295611a41a84611c895bb14e0d0cdc2164fdf037972","result":"ok"}, + {"name":"a space before","lang":"es","size":2048,"set":[{"at":5,"word":"2070616c616166"}],"sha256":"382f4bf269831d42e0ce019b63551fe99c0290419dcc7a56002a1c2c0f0b587a","result":"line 6, \" palaaf\", holds U+0020, which is not in the alphabet of \"es\""}, + {"name":"a space after","lang":"es","size":2048,"set":[{"at":5,"word":"70616c61616620"}],"sha256":"b538a1983df04e91d58774665aefc9b3ab22a1122c2a0cd380d93c1ebe1a7af5","result":"line 6, \"palaaf \", holds U+0020, which is not in the alphabet of \"es\""}, + {"name":"a tab inside","lang":"es","size":2048,"set":[{"at":5,"word":"70616c096166"}],"sha256":"0bbf370209dd5189292c89a5c0c337a6059affcf8771706b0ab1aef66e30cb6a","result":"line 6, \"pal\\taf\", is not one word of 3 or more letters"}, + {"name":"NBSP inside","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc2a06166"}],"sha256":"09cc345e8cedaeb60f7021c558100348ae482219f4184f7672661bb7872c21e5","result":"line 6, \"pal\\u00a0af\", is not one word of 3 or more letters"}, + {"name":"NEL inside","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc2856166"}],"sha256":"066ac85c3b4af72f1d3976b29c5809d0a4182d7dc3ba1c09eef2ebaedf1f9ebd","result":"line 6, \"pal\\u0085af\", is not one word of 3 or more letters"}, + {"name":"the ideographic space inside","lang":"es","size":2048,"set":[{"at":5,"word":"70616ce380806166"}],"sha256":"36bd83e640c63002bccfac2b6b34ce4f4bec6d0e92bbddeca871adf0c3e6172d","result":"line 6, \"pal\\u3000af\", is not one word of 3 or more letters"}, + {"name":"LS inside","lang":"es","size":2048,"set":[{"at":5,"word":"70616ce280a86166"}],"sha256":"b545bea83ab3d4b7dcaaa8e5b77cec190f8bf4273a0b38884225f332bfc2972d","result":"line 6, \"pal\\u2028af\", is not one word of 3 or more letters"}, + {"name":"an LF inside","lang":"es","size":2048,"set":[{"at":5,"word":"70616c0a6166"}],"sha256":"c48562076662e79dbd764e23894898f217a1f1f97f1abb2e9299ba7ac420afed","result":"line 6, \"pal\\naf\", is not one word of 3 or more letters"}, + {"name":"two runes and ZWSP: the count before the runes","lang":"es","size":2048,"set":[{"at":5,"word":"70e2808b"}],"sha256":"3e03fc5d9a4c0ac2c2e777da46e79cc19f9b9df80b34aa1457ede9fa5d1c7788","result":"line 6, \"p\\u200b\", is not one word of 3 or more letters"}, + {"name":"three letters with a mark that goes: two","lang":"es","size":2048,"set":[{"at":5,"word":"7061cc81"}],"sha256":"4338fbbae7ca23244246854fbe205ce59fb5871bbdd9cf0a2410e3db4c8f5c5d","result":"line 6, \"pa\u0301\", is not one word of 3 or more letters"}, + {"name":"a\u0301b, two letters once normalized","lang":"es","size":2048,"set":[{"at":5,"word":"61cc8162"}],"sha256":"b302b105aa962d188c2a193a6e42138aac9a7748df2be22327e119b21fdb6868","result":"line 6, \"a\u0301b\", is not one word of 3 or more letters"}, + {"name":"a control","lang":"es","size":2048,"set":[{"at":5,"word":"70616c016166"}],"sha256":"6288c09787e3af1bb5058c78bd33f441f4c8835bd59f276b16233c62300304ea","result":"line 6: wordkey: the words hold the control character U+0001"}, + {"name":"DEL","lang":"es","size":2048,"set":[{"at":5,"word":"70616c7f6166"}],"sha256":"30f93486be369882aedc5198f463e57331b4d7297af5f18afbf3895280437850","result":"line 6: wordkey: the words hold the control character U+007F"}, + {"name":"a C1 control","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc2806166"}],"sha256":"f015c53765dede22e047bd2402a945e9c56227b5889bcc226da11ff4ab1b5059","result":"line 6: wordkey: the words hold the control character U+0080"}, + {"name":"a control and a capital: the runes before the alphabet","lang":"es","size":2048,"set":[{"at":5,"word":"50616c016166"}],"sha256":"8195b293f594de3c0e5b556f54a2a87cf02266b26f74ba76f4c0aaf2ef5b3b8f","result":"line 6: wordkey: the words hold the control character U+0001"}, + {"name":"a soft hyphen","lang":"es","size":2048,"set":[{"at":5,"word":"7061c2ad"}],"sha256":"b87ae826ab91465b27cd82974898617afc29f293253546aec71fb7f1a598f949","result":"line 6: wordkey: the words hold the invisible character U+00AD"}, + {"name":"ZWJ","lang":"es","size":2048,"set":[{"at":5,"word":"70616ce2808d6166"}],"sha256":"2859e13c093ce340b7c2f937bc4470f36680100cd7fba471e7eb13d6f50c5e84","result":"line 6: wordkey: the words hold the invisible character U+200D"}, + {"name":"a byte order mark","lang":"es","size":2048,"set":[{"at":5,"word":"efbbbf70616c616166"}],"sha256":"3c9cef5930c2d943eee1019ad595c2a723b15a8aef3e2aa6134c2fc24d28db76","result":"line 6: wordkey: the words hold the invisible character U+FEFF"}, + {"name":"an unassigned code point","lang":"es","size":2048,"set":[{"at":5,"word":"70616ccdb8"}],"sha256":"8bbd2df9847132be8c2e1aefecd699fb6100a242cc550bf89af79f23125bf925","result":"line 6: wordkey: the words hold U+0378, unassigned in Unicode 18.0.0"}, + {"name":"a noncharacter","lang":"es","size":2048,"set":[{"at":5,"word":"70616cefbfbe"}],"sha256":"e5b2f98df9529f872db3a5c46d57b9275d0f47128fc5d80279ebccec05770220","result":"line 6: wordkey: the words hold U+FFFE, unassigned in Unicode 18.0.0"}, + {"name":"a tag","lang":"es","size":2048,"set":[{"at":5,"word":"70616cf3a081816166"}],"sha256":"2ce05d430f2683ae4add6f38a3009b9af978608094c0de404366add14dbccb6d","result":"line 6: wordkey: the words hold the invisible character U+E0041"}, + {"name":"the letters of the alphabet","lang":"es","size":2048,"set":[{"at":5,"word":"6162636465666768696a6b6c6d6e6f707172737475767778797ac3a1c3a9c3adc3b3c3bac3bcc3b1"}],"sha256":"171612e5b64aca979e9f98d04c632252f41dd2c8b419d30b919a664ded7523c5","result":"ok"}, + {"name":"an acute accent in NFD","lang":"es","size":2048,"set":[{"at":5,"word":"70616c61cc8165"}],"sha256":"18d9d3d9837a8ab1d6236bf70454102e4cd62d78858ecaf5429a3bf5012ac681","result":"line 6, \"pala\u0301e\", holds U+0301, which is not in the alphabet of \"es\""}, + {"name":"a diaeresis in NFD","lang":"es","size":2048,"set":[{"at":5,"word":"70616c6161cc88"}],"sha256":"687b6e86c51a3298a4ce78742495d25302cc11228576f83bba7788188c7086d3","result":"line 6, \"palaa\u0308\", holds U+0308, which is not in the alphabet of \"es\""}, + {"name":"a tilde in NFD","lang":"es","size":2048,"set":[{"at":5,"word":"70616ecc836f"}],"sha256":"88e23891893b369e4cf68becc9cfe9fd84444c5002e353f87a684cd6a564d2c4","result":"line 6, \"pan\u0303o\", holds U+0303, which is not in the alphabet of \"es\""}, + {"name":"\u00c1, a capital with an accent","lang":"es","size":2048,"set":[{"at":5,"word":"c3816261636f"}],"sha256":"fc9405a1716bc62e7b194732c3a9bbc7c42ded47d7c169c2579d25290522e9bf","result":"line 6, \"\u00c1baco\", holds U+00C1, which is not in the alphabet of \"es\""}, + {"name":"\u00d1, a capital","lang":"es","size":2048,"set":[{"at":5,"word":"c391616e64c3ba"}],"sha256":"d48bed60f8744c2fc3f0f34a5e3f4e867e734f5fb7cbef82af6086e710b88d3c","result":"line 6, \"\u00d1and\u00fa\", holds U+00D1, which is not in the alphabet of \"es\""}, + {"name":"a grave accent","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc3a061"}],"sha256":"52748dc437c58a824f554dc2f870a5f49db3833e2a34023324d407e7b80cc658","result":"line 6, \"pal\u00e0a\", holds U+00E0, which is not in the alphabet of \"es\""}, + {"name":"a circumflex","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc3a261"}],"sha256":"e190dd09884acccb334e299438fc7eae1a8bd1d982a8197eac610977c9c14ef9","result":"line 6, \"pal\u00e2a\", holds U+00E2, which is not in the alphabet of \"es\""}, + {"name":"\u00e4","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc3a461"}],"sha256":"76c4d1e2b9821df83c705e792119b514c666877449ff97373aa83fb5eb3c6505","result":"line 6, \"pal\u00e4a\", holds U+00E4, which is not in the alphabet of \"es\""}, + {"name":"\u00e7","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc3a761"}],"sha256":"8bf7d649fd58ab3c1a5a432a162c43f174e56e0188a3c599025f5cdbf3df2e1a","result":"line 6, \"pal\u00e7a\", holds U+00E7, which is not in the alphabet of \"es\""}, + {"name":"\u00f6","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc3b661"}],"sha256":"590bcda940c5ae0f8f30c1f6d1b941ac0707e933f4af993c1072970cde920170","result":"line 6, \"pal\u00f6a\", holds U+00F6, which is not in the alphabet of \"es\""}, + {"name":"\u00fd","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc3bd61"}],"sha256":"72af7d5747ee97e630664d5fb5efd0f51c863d55e7424b7ee9ecac8aa1076b9b","result":"line 6, \"pal\u00fda\", holds U+00FD, which is not in the alphabet of \"es\""}, + {"name":"\u00df","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc39f61"}],"sha256":"d73bd84a27377847b8e0a039490c0924cd6e8dec83547f0913151bcd2a292d0c","result":"line 6, \"pal\u00dfa\", holds U+00DF, which is not in the alphabet of \"es\""}, + {"name":"a Cyrillic a","lang":"es","size":2048,"set":[{"at":5,"word":"70616cd0b061"}],"sha256":"9f1959893c6bbf097866272a1eb73a30b29356f6db232d10e48ea706ad95da94","result":"line 6, \"pal\u0430a\", holds U+0430, which is not in the alphabet of \"es\""}, + {"name":"a Greek omicron","lang":"es","size":2048,"set":[{"at":5,"word":"70616ccebf61"}],"sha256":"51591f2a3d611a835b14977093687b0fb0b82264aea304e847ec4e9a92e60721","result":"line 6, \"pal\u03bfa\", holds U+03BF, which is not in the alphabet of \"es\""}, + {"name":"a full-width a","lang":"es","size":2048,"set":[{"at":5,"word":"70616cefbd8161"}],"sha256":"466a6f43f3775f8009531c7200ab2d2cb01770da643e39e208b503a6adc8817e","result":"line 6, \"pal\uff41a\", holds U+FF41, which is not in the alphabet of \"es\""}, + {"name":"a mathematical bold a","lang":"es","size":2048,"set":[{"at":5,"word":"70616cf09d909a61"}],"sha256":"9cdb9150c16635f18c1edeb4a99be2b972dbe3534b96bc45518cb2be7c45d3c1","result":"line 6, \"pal\ud835\udc1aa\", holds U+1D41A, which is not in the alphabet of \"es\""}, + {"name":"the Kelvin sign","lang":"es","size":2048,"set":[{"at":5,"word":"70616ce284aa61"}],"sha256":"8296c53f65135f54af51349dda6315556aa5ab7c476bf09faafbbb3579567491","result":"line 6, \"pal\u212aa\", holds U+212A, which is not in the alphabet of \"es\""}, + {"name":"a dotless i","lang":"es","size":2048,"set":[{"at":5,"word":"70616cc4b161"}],"sha256":"acff79df5e69176c3bd51aa70d8a0f20de8593c97cdc8d3f32c450cf30fb587a","result":"line 6, \"pal\u0131a\", holds U+0131, which is not in the alphabet of \"es\""}, + {"name":"a hyphen","lang":"es","size":2048,"set":[{"at":5,"word":"70616c2d6166"}],"sha256":"5b316070132e5fe53051a1cc61aba7ec9c324a6b11e23ce9e062823e8765af24","result":"line 6, \"pal-af\", holds U+002D, which is not in the alphabet of \"es\""}, + {"name":"an apostrophe","lang":"es","size":2048,"set":[{"at":5,"word":"70616c276166"}],"sha256":"a2fcd25525cf45943776c7b07471982a531c997227c3757d2fa375611d666d19","result":"line 6, \"pal'af\", holds U+0027, which is not in the alphabet of \"es\""}, + {"name":"a backtick and a brace, around a to z","lang":"es","size":2048,"set":[{"at":5,"word":"70616c607b"}],"sha256":"a1bf9fc3215154c3b002a53a4bcaeca5a30c21b7108dbfd23fc762e0da7d1e99","result":"line 6, \"pal`{\", holds U+0060, which is not in the alphabet of \"es\""}, + {"name":"an emoji","lang":"es","size":2048,"set":[{"at":5,"word":"70616cf09f9880"}],"sha256":"9a8aacbd11b71319a98472e41974ab3b78b4a8781ae33fa170220f4f5f2f84bc","result":"line 6, \"pal\ud83d\ude00\", holds U+1F600, which is not in the alphabet of \"es\""}, + {"name":"a byte that is not valid UTF-8","lang":"es","size":2048,"set":[{"at":5,"word":"70616cff6161"}],"sha256":"028e9203eda7205fb204a2bed86bb9126c70f80d3fcf2ccc59544d5a09a3dd45","result":"line 6, \"pal\\xffaa\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"a surrogate in UTF-8 bytes","lang":"es","size":2048,"set":[{"at":5,"word":"eda080616161"}],"sha256":"c175fc03314b4ac1a469dc46ab6888e6e0b62facd72f485e7369569a809e2ee0","result":"line 6, \"\\xed\\xa0\\x80aaa\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"a sequence cut short","lang":"es","size":2048,"set":[{"at":5,"word":"70616c61c3"}],"sha256":"b982ef907d87e08d79e038d579bbe0988a8c7eb190b83de73593168ea992ac4f","result":"line 6, \"pala\\xc3\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"an overlong NUL","lang":"es","size":2048,"set":[{"at":5,"word":"c080616161"}],"sha256":"536087a6fecd4b3a8ba068f8ab988149cb22ea63f09fa6878693cff47abed313","result":"line 6, \"\\xc0\\x80aaa\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"U+FFFD itself","lang":"es","size":2048,"set":[{"at":5,"word":"70616cefbfbd6161"}],"sha256":"a59f04e2deb66cb73a0487f13cf8d9255e3fb1594475ffd82ac424406ae686e7","result":"line 6, \"pal\ufffdaa\", holds U+FFFD, which is not in the alphabet of \"es\""}, + {"name":"a\u00f1o and ano","lang":"es","size":2048,"set":[{"at":5,"word":"61c3b16f"},{"at":6,"word":"616e6f"}],"sha256":"8d616f5737a177219aa2531b9751d2e2ab0ccd7828f8c119d6cbca48fe17bf66","result":"line 7, \"ano\", is the same word as \"a\u00f1o\" once normalized"}, + {"name":"ping\u00fcino and pinguino","lang":"es","size":2048,"set":[{"at":5,"word":"70696e6775696e6f"},{"at":9,"word":"70696e67c3bc696e6f"}],"sha256":"ea28b2e6cef6fda1e67bb96638c93fe6634bd4cc5ce2dde4f0331aea64d130f6","result":"line 10, \"ping\u00fcino\", is the same word as \"pinguino\" once normalized"}, + {"name":"the same word, the first of the list last","lang":"es","size":2048,"append":["70616c616161"],"sha256":"24692d3331d9c5e2d9aeca9de2a6a89fbd941ac3237f68d901a291e1dfe52fa7","result":"line 2049, \"palaaa\", is the same word as \"palaaa\" once normalized"}, + {"name":"a capital of a word of the list: the alphabet before the same word","lang":"es","size":2048,"set":[{"at":5,"word":"50414c414145"}],"sha256":"bf4af0c60850edee7eb20f7e575d4b14fa16a193bc93a1333d4e502baea53df3","result":"line 6, \"PALAAE\", holds U+0050, which is not in the alphabet of \"es\""}, + {"name":"an error at line 4 and another at line 6","lang":"es","size":2048,"set":[{"at":3,"word":"4d616c"},{"at":5,"word":"7061"}],"sha256":"61e1d0c145b794b21f87db1a07f5bec75a104e9a03e0e64f8eb42dd584ccadf9","result":"line 4, \"Mal\", holds U+004D, which is not in the alphabet of \"es\""}, + {"name":"an error at the last line","lang":"es","size":2048,"set":[{"at":2047,"word":"78"}],"sha256":"9ccabe185e9b3a34151eaaa0c0a6d6d39488c5fac1ea9e72c898bf8ae43917a0","result":"line 2048, \"x\", is not one word of 3 or more letters"}, + {"name":"an empty last line","lang":"es","size":2048,"append":[""],"sha256":"40e5649349cf1302065f2ceda7e7c4aec69e423fb8916c20b4445b229df6add1","result":"line 2049, \"\", is not one word of 3 or more letters"} + ], + "alphabet_results": [ + {"rune":0,"result":"line 1: wordkey: the words hold the control character U+0000"}, + {"rune":1,"result":"line 1: wordkey: the words hold the control character U+0001"}, + {"rune":2,"result":"line 1: wordkey: the words hold the control character U+0002"}, + {"rune":3,"result":"line 1: wordkey: the words hold the control character U+0003"}, + {"rune":4,"result":"line 1: wordkey: the words hold the control character U+0004"}, + {"rune":5,"result":"line 1: wordkey: the words hold the control character U+0005"}, + {"rune":6,"result":"line 1: wordkey: the words hold the control character U+0006"}, + {"rune":7,"result":"line 1: wordkey: the words hold the control character U+0007"}, + {"rune":8,"result":"line 1: wordkey: the words hold the control character U+0008"}, + {"rune":9,"result":"line 1, \"pala\\tzz\", is not one word of 3 or more letters"}, + {"rune":10,"result":"line 1, \"pala\\nzz\", is not one word of 3 or more letters"}, + {"rune":11,"result":"line 1, \"pala\\vzz\", is not one word of 3 or more letters"}, + {"rune":12,"result":"line 1, \"pala\\fzz\", is not one word of 3 or more letters"}, + {"rune":13,"result":"line 1, \"pala\\rzz\", is not one word of 3 or more letters"}, + {"rune":14,"result":"line 1: wordkey: the words hold the control character U+000E"}, + {"rune":15,"result":"line 1: wordkey: the words hold the control character U+000F"}, + {"rune":16,"result":"line 1: wordkey: the words hold the control character U+0010"}, + {"rune":17,"result":"line 1: wordkey: the words hold the control character U+0011"}, + {"rune":18,"result":"line 1: wordkey: the words hold the control character U+0012"}, + {"rune":19,"result":"line 1: wordkey: the words hold the control character U+0013"}, + {"rune":20,"result":"line 1: wordkey: the words hold the control character U+0014"}, + {"rune":21,"result":"line 1: wordkey: the words hold the control character U+0015"}, + {"rune":22,"result":"line 1: wordkey: the words hold the control character U+0016"}, + {"rune":23,"result":"line 1: wordkey: the words hold the control character U+0017"}, + {"rune":24,"result":"line 1: wordkey: the words hold the control character U+0018"}, + {"rune":25,"result":"line 1: wordkey: the words hold the control character U+0019"}, + {"rune":26,"result":"line 1: wordkey: the words hold the control character U+001A"}, + {"rune":27,"result":"line 1: wordkey: the words hold the control character U+001B"}, + {"rune":28,"result":"line 1: wordkey: the words hold the control character U+001C"}, + {"rune":29,"result":"line 1: wordkey: the words hold the control character U+001D"}, + {"rune":30,"result":"line 1: wordkey: the words hold the control character U+001E"}, + {"rune":31,"result":"line 1: wordkey: the words hold the control character U+001F"}, + {"rune":32,"result":"line 1, \"pala zz\", is not one word of 3 or more letters"}, + {"rune":33,"result":"line 1, \"pala!zz\", holds U+0021, which is not in the alphabet of \"es\""}, + {"rune":34,"result":"line 1, \"pala\\\"zz\", holds U+0022, which is not in the alphabet of \"es\""}, + {"rune":35,"result":"line 1, \"pala#zz\", holds U+0023, which is not in the alphabet of \"es\""}, + {"rune":36,"result":"line 1, \"pala$zz\", holds U+0024, which is not in the alphabet of \"es\""}, + {"rune":37,"result":"line 1, \"pala%zz\", holds U+0025, which is not in the alphabet of \"es\""}, + {"rune":38,"result":"line 1, \"pala&zz\", holds U+0026, which is not in the alphabet of \"es\""}, + {"rune":39,"result":"line 1, \"pala'zz\", holds U+0027, which is not in the alphabet of \"es\""}, + {"rune":40,"result":"line 1, \"pala(zz\", holds U+0028, which is not in the alphabet of \"es\""}, + {"rune":41,"result":"line 1, \"pala)zz\", holds U+0029, which is not in the alphabet of \"es\""}, + {"rune":42,"result":"line 1, \"pala*zz\", holds U+002A, which is not in the alphabet of \"es\""}, + {"rune":43,"result":"line 1, \"pala+zz\", holds U+002B, which is not in the alphabet of \"es\""}, + {"rune":44,"result":"line 1, \"pala,zz\", holds U+002C, which is not in the alphabet of \"es\""}, + {"rune":45,"result":"line 1, \"pala-zz\", holds U+002D, which is not in the alphabet of \"es\""}, + {"rune":46,"result":"line 1, \"pala.zz\", holds U+002E, which is not in the alphabet of \"es\""}, + {"rune":47,"result":"line 1, \"pala/zz\", holds U+002F, which is not in the alphabet of \"es\""}, + {"rune":48,"result":"line 1, \"pala0zz\", holds U+0030, which is not in the alphabet of \"es\""}, + {"rune":49,"result":"line 1, \"pala1zz\", holds U+0031, which is not in the alphabet of \"es\""}, + {"rune":50,"result":"line 1, \"pala2zz\", holds U+0032, which is not in the alphabet of \"es\""}, + {"rune":51,"result":"line 1, \"pala3zz\", holds U+0033, which is not in the alphabet of \"es\""}, + {"rune":52,"result":"line 1, \"pala4zz\", holds U+0034, which is not in the alphabet of \"es\""}, + {"rune":53,"result":"line 1, \"pala5zz\", holds U+0035, which is not in the alphabet of \"es\""}, + {"rune":54,"result":"line 1, \"pala6zz\", holds U+0036, which is not in the alphabet of \"es\""}, + {"rune":55,"result":"line 1, \"pala7zz\", holds U+0037, which is not in the alphabet of \"es\""}, + {"rune":56,"result":"line 1, \"pala8zz\", holds U+0038, which is not in the alphabet of \"es\""}, + {"rune":57,"result":"line 1, \"pala9zz\", holds U+0039, which is not in the alphabet of \"es\""}, + {"rune":58,"result":"line 1, \"pala:zz\", holds U+003A, which is not in the alphabet of \"es\""}, + {"rune":59,"result":"line 1, \"pala;zz\", holds U+003B, which is not in the alphabet of \"es\""}, + {"rune":60,"result":"line 1, \"palazz\", holds U+003E, which is not in the alphabet of \"es\""}, + {"rune":63,"result":"line 1, \"pala?zz\", holds U+003F, which is not in the alphabet of \"es\""}, + {"rune":64,"result":"line 1, \"pala@zz\", holds U+0040, which is not in the alphabet of \"es\""}, + {"rune":65,"result":"line 1, \"palaAzz\", holds U+0041, which is not in the alphabet of \"es\""}, + {"rune":66,"result":"line 1, \"palaBzz\", holds U+0042, which is not in the alphabet of \"es\""}, + {"rune":67,"result":"line 1, \"palaCzz\", holds U+0043, which is not in the alphabet of \"es\""}, + {"rune":68,"result":"line 1, \"palaDzz\", holds U+0044, which is not in the alphabet of \"es\""}, + {"rune":69,"result":"line 1, \"palaEzz\", holds U+0045, which is not in the alphabet of \"es\""}, + {"rune":70,"result":"line 1, \"palaFzz\", holds U+0046, which is not in the alphabet of \"es\""}, + {"rune":71,"result":"line 1, \"palaGzz\", holds U+0047, which is not in the alphabet of \"es\""}, + {"rune":72,"result":"line 1, \"palaHzz\", holds U+0048, which is not in the alphabet of \"es\""}, + {"rune":73,"result":"line 1, \"palaIzz\", holds U+0049, which is not in the alphabet of \"es\""}, + {"rune":74,"result":"line 1, \"palaJzz\", holds U+004A, which is not in the alphabet of \"es\""}, + {"rune":75,"result":"line 1, \"palaKzz\", holds U+004B, which is not in the alphabet of \"es\""}, + {"rune":76,"result":"line 1, \"palaLzz\", holds U+004C, which is not in the alphabet of \"es\""}, + {"rune":77,"result":"line 1, \"palaMzz\", holds U+004D, which is not in the alphabet of \"es\""}, + {"rune":78,"result":"line 1, \"palaNzz\", holds U+004E, which is not in the alphabet of \"es\""}, + {"rune":79,"result":"line 1, \"palaOzz\", holds U+004F, which is not in the alphabet of \"es\""}, + {"rune":80,"result":"line 1, \"palaPzz\", holds U+0050, which is not in the alphabet of \"es\""}, + {"rune":81,"result":"line 1, \"palaQzz\", holds U+0051, which is not in the alphabet of \"es\""}, + {"rune":82,"result":"line 1, \"palaRzz\", holds U+0052, which is not in the alphabet of \"es\""}, + {"rune":83,"result":"line 1, \"palaSzz\", holds U+0053, which is not in the alphabet of \"es\""}, + {"rune":84,"result":"line 1, \"palaTzz\", holds U+0054, which is not in the alphabet of \"es\""}, + {"rune":85,"result":"line 1, \"palaUzz\", holds U+0055, which is not in the alphabet of \"es\""}, + {"rune":86,"result":"line 1, \"palaVzz\", holds U+0056, which is not in the alphabet of \"es\""}, + {"rune":87,"result":"line 1, \"palaWzz\", holds U+0057, which is not in the alphabet of \"es\""}, + {"rune":88,"result":"line 1, \"palaXzz\", holds U+0058, which is not in the alphabet of \"es\""}, + {"rune":89,"result":"line 1, \"palaYzz\", holds U+0059, which is not in the alphabet of \"es\""}, + {"rune":90,"result":"line 1, \"palaZzz\", holds U+005A, which is not in the alphabet of \"es\""}, + {"rune":91,"result":"line 1, \"pala[zz\", holds U+005B, which is not in the alphabet of \"es\""}, + {"rune":92,"result":"line 1, \"pala\\\\zz\", holds U+005C, which is not in the alphabet of \"es\""}, + {"rune":93,"result":"line 1, \"pala]zz\", holds U+005D, which is not in the alphabet of \"es\""}, + {"rune":94,"result":"line 1, \"pala^zz\", holds U+005E, which is not in the alphabet of \"es\""}, + {"rune":95,"result":"line 1, \"pala_zz\", holds U+005F, which is not in the alphabet of \"es\""}, + {"rune":96,"result":"line 1, \"pala`zz\", holds U+0060, which is not in the alphabet of \"es\""}, + {"rune":97,"result":"ok"}, + {"rune":98,"result":"ok"}, + {"rune":99,"result":"ok"}, + {"rune":100,"result":"ok"}, + {"rune":101,"result":"ok"}, + {"rune":102,"result":"ok"}, + {"rune":103,"result":"ok"}, + {"rune":104,"result":"ok"}, + {"rune":105,"result":"ok"}, + {"rune":106,"result":"ok"}, + {"rune":107,"result":"ok"}, + {"rune":108,"result":"ok"}, + {"rune":109,"result":"ok"}, + {"rune":110,"result":"ok"}, + {"rune":111,"result":"ok"}, + {"rune":112,"result":"ok"}, + {"rune":113,"result":"ok"}, + {"rune":114,"result":"ok"}, + {"rune":115,"result":"ok"}, + {"rune":116,"result":"ok"}, + {"rune":117,"result":"ok"}, + {"rune":118,"result":"ok"}, + {"rune":119,"result":"ok"}, + {"rune":120,"result":"ok"}, + {"rune":121,"result":"ok"}, + {"rune":122,"result":"ok"}, + {"rune":123,"result":"line 1, \"pala{zz\", holds U+007B, which is not in the alphabet of \"es\""}, + {"rune":124,"result":"line 1, \"pala|zz\", holds U+007C, which is not in the alphabet of \"es\""}, + {"rune":125,"result":"line 1, \"pala}zz\", holds U+007D, which is not in the alphabet of \"es\""}, + {"rune":126,"result":"line 1, \"pala~zz\", holds U+007E, which is not in the alphabet of \"es\""}, + {"rune":127,"result":"line 1: wordkey: the words hold the control character U+007F"}, + {"rune":128,"result":"line 1: wordkey: the words hold the control character U+0080"}, + {"rune":129,"result":"line 1: wordkey: the words hold the control character U+0081"}, + {"rune":130,"result":"line 1: wordkey: the words hold the control character U+0082"}, + {"rune":131,"result":"line 1: wordkey: the words hold the control character U+0083"}, + {"rune":132,"result":"line 1: wordkey: the words hold the control character U+0084"}, + {"rune":133,"result":"line 1, \"pala\\u0085zz\", is not one word of 3 or more letters"}, + {"rune":134,"result":"line 1: wordkey: the words hold the control character U+0086"}, + {"rune":135,"result":"line 1: wordkey: the words hold the control character U+0087"}, + {"rune":136,"result":"line 1: wordkey: the words hold the control character U+0088"}, + {"rune":137,"result":"line 1: wordkey: the words hold the control character U+0089"}, + {"rune":138,"result":"line 1: wordkey: the words hold the control character U+008A"}, + {"rune":139,"result":"line 1: wordkey: the words hold the control character U+008B"}, + {"rune":140,"result":"line 1: wordkey: the words hold the control character U+008C"}, + {"rune":141,"result":"line 1: wordkey: the words hold the control character U+008D"}, + {"rune":142,"result":"line 1: wordkey: the words hold the control character U+008E"}, + {"rune":143,"result":"line 1: wordkey: the words hold the control character U+008F"}, + {"rune":144,"result":"line 1: wordkey: the words hold the control character U+0090"}, + {"rune":145,"result":"line 1: wordkey: the words hold the control character U+0091"}, + {"rune":146,"result":"line 1: wordkey: the words hold the control character U+0092"}, + {"rune":147,"result":"line 1: wordkey: the words hold the control character U+0093"}, + {"rune":148,"result":"line 1: wordkey: the words hold the control character U+0094"}, + {"rune":149,"result":"line 1: wordkey: the words hold the control character U+0095"}, + {"rune":150,"result":"line 1: wordkey: the words hold the control character U+0096"}, + {"rune":151,"result":"line 1: wordkey: the words hold the control character U+0097"}, + {"rune":152,"result":"line 1: wordkey: the words hold the control character U+0098"}, + {"rune":153,"result":"line 1: wordkey: the words hold the control character U+0099"}, + {"rune":154,"result":"line 1: wordkey: the words hold the control character U+009A"}, + {"rune":155,"result":"line 1: wordkey: the words hold the control character U+009B"}, + {"rune":156,"result":"line 1: wordkey: the words hold the control character U+009C"}, + {"rune":157,"result":"line 1: wordkey: the words hold the control character U+009D"}, + {"rune":158,"result":"line 1: wordkey: the words hold the control character U+009E"}, + {"rune":159,"result":"line 1: wordkey: the words hold the control character U+009F"}, + {"rune":160,"result":"line 1, \"pala\\u00a0zz\", is not one word of 3 or more letters"}, + {"rune":161,"result":"line 1, \"pala\u00a1zz\", holds U+00A1, which is not in the alphabet of \"es\""}, + {"rune":162,"result":"line 1, \"pala\u00a2zz\", holds U+00A2, which is not in the alphabet of \"es\""}, + {"rune":163,"result":"line 1, \"pala\u00a3zz\", holds U+00A3, which is not in the alphabet of \"es\""}, + {"rune":164,"result":"line 1, \"pala\u00a4zz\", holds U+00A4, which is not in the alphabet of \"es\""}, + {"rune":165,"result":"line 1, \"pala\u00a5zz\", holds U+00A5, which is not in the alphabet of \"es\""}, + {"rune":166,"result":"line 1, \"pala\u00a6zz\", holds U+00A6, which is not in the alphabet of \"es\""}, + {"rune":167,"result":"line 1, \"pala\u00a7zz\", holds U+00A7, which is not in the alphabet of \"es\""}, + {"rune":168,"result":"line 1, \"pala\u00a8zz\", holds U+00A8, which is not in the alphabet of \"es\""}, + {"rune":169,"result":"line 1, \"pala\u00a9zz\", holds U+00A9, which is not in the alphabet of \"es\""}, + {"rune":170,"result":"line 1, \"pala\u00aazz\", holds U+00AA, which is not in the alphabet of \"es\""}, + {"rune":171,"result":"line 1, \"pala\u00abzz\", holds U+00AB, which is not in the alphabet of \"es\""}, + {"rune":172,"result":"line 1, \"pala\u00aczz\", holds U+00AC, which is not in the alphabet of \"es\""}, + {"rune":173,"result":"line 1: wordkey: the words hold the invisible character U+00AD"}, + {"rune":174,"result":"line 1, \"pala\u00aezz\", holds U+00AE, which is not in the alphabet of \"es\""}, + {"rune":175,"result":"line 1, \"pala\u00afzz\", holds U+00AF, which is not in the alphabet of \"es\""}, + {"rune":176,"result":"line 1, \"pala\u00b0zz\", holds U+00B0, which is not in the alphabet of \"es\""}, + {"rune":177,"result":"line 1, \"pala\u00b1zz\", holds U+00B1, which is not in the alphabet of \"es\""}, + {"rune":178,"result":"line 1, \"pala\u00b2zz\", holds U+00B2, which is not in the alphabet of \"es\""}, + {"rune":179,"result":"line 1, \"pala\u00b3zz\", holds U+00B3, which is not in the alphabet of \"es\""}, + {"rune":180,"result":"line 1, \"pala\u00b4zz\", holds U+00B4, which is not in the alphabet of \"es\""}, + {"rune":181,"result":"line 1, \"pala\u00b5zz\", holds U+00B5, which is not in the alphabet of \"es\""}, + {"rune":182,"result":"line 1, \"pala\u00b6zz\", holds U+00B6, which is not in the alphabet of \"es\""}, + {"rune":183,"result":"line 1, \"pala\u00b7zz\", holds U+00B7, which is not in the alphabet of \"es\""}, + {"rune":184,"result":"line 1, \"pala\u00b8zz\", holds U+00B8, which is not in the alphabet of \"es\""}, + {"rune":185,"result":"line 1, \"pala\u00b9zz\", holds U+00B9, which is not in the alphabet of \"es\""}, + {"rune":186,"result":"line 1, \"pala\u00bazz\", holds U+00BA, which is not in the alphabet of \"es\""}, + {"rune":187,"result":"line 1, \"pala\u00bbzz\", holds U+00BB, which is not in the alphabet of \"es\""}, + {"rune":188,"result":"line 1, \"pala\u00bczz\", holds U+00BC, which is not in the alphabet of \"es\""}, + {"rune":189,"result":"line 1, \"pala\u00bdzz\", holds U+00BD, which is not in the alphabet of \"es\""}, + {"rune":190,"result":"line 1, \"pala\u00bezz\", holds U+00BE, which is not in the alphabet of \"es\""}, + {"rune":191,"result":"line 1, \"pala\u00bfzz\", holds U+00BF, which is not in the alphabet of \"es\""}, + {"rune":192,"result":"line 1, \"pala\u00c0zz\", holds U+00C0, which is not in the alphabet of \"es\""}, + {"rune":193,"result":"line 1, \"pala\u00c1zz\", holds U+00C1, which is not in the alphabet of \"es\""}, + {"rune":194,"result":"line 1, \"pala\u00c2zz\", holds U+00C2, which is not in the alphabet of \"es\""}, + {"rune":195,"result":"line 1, \"pala\u00c3zz\", holds U+00C3, which is not in the alphabet of \"es\""}, + {"rune":196,"result":"line 1, \"pala\u00c4zz\", holds U+00C4, which is not in the alphabet of \"es\""}, + {"rune":197,"result":"line 1, \"pala\u00c5zz\", holds U+00C5, which is not in the alphabet of \"es\""}, + {"rune":198,"result":"line 1, \"pala\u00c6zz\", holds U+00C6, which is not in the alphabet of \"es\""}, + {"rune":199,"result":"line 1, \"pala\u00c7zz\", holds U+00C7, which is not in the alphabet of \"es\""}, + {"rune":200,"result":"line 1, \"pala\u00c8zz\", holds U+00C8, which is not in the alphabet of \"es\""}, + {"rune":201,"result":"line 1, \"pala\u00c9zz\", holds U+00C9, which is not in the alphabet of \"es\""}, + {"rune":202,"result":"line 1, \"pala\u00cazz\", holds U+00CA, which is not in the alphabet of \"es\""}, + {"rune":203,"result":"line 1, \"pala\u00cbzz\", holds U+00CB, which is not in the alphabet of \"es\""}, + {"rune":204,"result":"line 1, \"pala\u00cczz\", holds U+00CC, which is not in the alphabet of \"es\""}, + {"rune":205,"result":"line 1, \"pala\u00cdzz\", holds U+00CD, which is not in the alphabet of \"es\""}, + {"rune":206,"result":"line 1, \"pala\u00cezz\", holds U+00CE, which is not in the alphabet of \"es\""}, + {"rune":207,"result":"line 1, \"pala\u00cfzz\", holds U+00CF, which is not in the alphabet of \"es\""}, + {"rune":208,"result":"line 1, \"pala\u00d0zz\", holds U+00D0, which is not in the alphabet of \"es\""}, + {"rune":209,"result":"line 1, \"pala\u00d1zz\", holds U+00D1, which is not in the alphabet of \"es\""}, + {"rune":210,"result":"line 1, \"pala\u00d2zz\", holds U+00D2, which is not in the alphabet of \"es\""}, + {"rune":211,"result":"line 1, \"pala\u00d3zz\", holds U+00D3, which is not in the alphabet of \"es\""}, + {"rune":212,"result":"line 1, \"pala\u00d4zz\", holds U+00D4, which is not in the alphabet of \"es\""}, + {"rune":213,"result":"line 1, \"pala\u00d5zz\", holds U+00D5, which is not in the alphabet of \"es\""}, + {"rune":214,"result":"line 1, \"pala\u00d6zz\", holds U+00D6, which is not in the alphabet of \"es\""}, + {"rune":215,"result":"line 1, \"pala\u00d7zz\", holds U+00D7, which is not in the alphabet of \"es\""}, + {"rune":216,"result":"line 1, \"pala\u00d8zz\", holds U+00D8, which is not in the alphabet of \"es\""}, + {"rune":217,"result":"line 1, \"pala\u00d9zz\", holds U+00D9, which is not in the alphabet of \"es\""}, + {"rune":218,"result":"line 1, \"pala\u00dazz\", holds U+00DA, which is not in the alphabet of \"es\""}, + {"rune":219,"result":"line 1, \"pala\u00dbzz\", holds U+00DB, which is not in the alphabet of \"es\""}, + {"rune":220,"result":"line 1, \"pala\u00dczz\", holds U+00DC, which is not in the alphabet of \"es\""}, + {"rune":221,"result":"line 1, \"pala\u00ddzz\", holds U+00DD, which is not in the alphabet of \"es\""}, + {"rune":222,"result":"line 1, \"pala\u00dezz\", holds U+00DE, which is not in the alphabet of \"es\""}, + {"rune":223,"result":"line 1, \"pala\u00dfzz\", holds U+00DF, which is not in the alphabet of \"es\""}, + {"rune":224,"result":"line 1, \"pala\u00e0zz\", holds U+00E0, which is not in the alphabet of \"es\""}, + {"rune":225,"result":"ok"}, + {"rune":226,"result":"line 1, \"pala\u00e2zz\", holds U+00E2, which is not in the alphabet of \"es\""}, + {"rune":227,"result":"line 1, \"pala\u00e3zz\", holds U+00E3, which is not in the alphabet of \"es\""}, + {"rune":228,"result":"line 1, \"pala\u00e4zz\", holds U+00E4, which is not in the alphabet of \"es\""}, + {"rune":229,"result":"line 1, \"pala\u00e5zz\", holds U+00E5, which is not in the alphabet of \"es\""}, + {"rune":230,"result":"line 1, \"pala\u00e6zz\", holds U+00E6, which is not in the alphabet of \"es\""}, + {"rune":231,"result":"line 1, \"pala\u00e7zz\", holds U+00E7, which is not in the alphabet of \"es\""}, + {"rune":232,"result":"line 1, \"pala\u00e8zz\", holds U+00E8, which is not in the alphabet of \"es\""}, + {"rune":233,"result":"ok"}, + {"rune":234,"result":"line 1, \"pala\u00eazz\", holds U+00EA, which is not in the alphabet of \"es\""}, + {"rune":235,"result":"line 1, \"pala\u00ebzz\", holds U+00EB, which is not in the alphabet of \"es\""}, + {"rune":236,"result":"line 1, \"pala\u00eczz\", holds U+00EC, which is not in the alphabet of \"es\""}, + {"rune":237,"result":"ok"}, + {"rune":238,"result":"line 1, \"pala\u00eezz\", holds U+00EE, which is not in the alphabet of \"es\""}, + {"rune":239,"result":"line 1, \"pala\u00efzz\", holds U+00EF, which is not in the alphabet of \"es\""}, + {"rune":240,"result":"line 1, \"pala\u00f0zz\", holds U+00F0, which is not in the alphabet of \"es\""}, + {"rune":241,"result":"ok"}, + {"rune":242,"result":"line 1, \"pala\u00f2zz\", holds U+00F2, which is not in the alphabet of \"es\""}, + {"rune":243,"result":"ok"}, + {"rune":244,"result":"line 1, \"pala\u00f4zz\", holds U+00F4, which is not in the alphabet of \"es\""}, + {"rune":245,"result":"line 1, \"pala\u00f5zz\", holds U+00F5, which is not in the alphabet of \"es\""}, + {"rune":246,"result":"line 1, \"pala\u00f6zz\", holds U+00F6, which is not in the alphabet of \"es\""}, + {"rune":247,"result":"line 1, \"pala\u00f7zz\", holds U+00F7, which is not in the alphabet of \"es\""}, + {"rune":248,"result":"line 1, \"pala\u00f8zz\", holds U+00F8, which is not in the alphabet of \"es\""}, + {"rune":249,"result":"line 1, \"pala\u00f9zz\", holds U+00F9, which is not in the alphabet of \"es\""}, + {"rune":250,"result":"ok"}, + {"rune":251,"result":"line 1, \"pala\u00fbzz\", holds U+00FB, which is not in the alphabet of \"es\""}, + {"rune":252,"result":"ok"}, + {"rune":253,"result":"line 1, \"pala\u00fdzz\", holds U+00FD, which is not in the alphabet of \"es\""}, + {"rune":254,"result":"line 1, \"pala\u00fezz\", holds U+00FE, which is not in the alphabet of \"es\""}, + {"rune":255,"result":"line 1, \"pala\u00ffzz\", holds U+00FF, which is not in the alphabet of \"es\""}, + {"rune":256,"result":"line 1, \"pala\u0100zz\", holds U+0100, which is not in the alphabet of \"es\""}, + {"rune":257,"result":"line 1, \"pala\u0101zz\", holds U+0101, which is not in the alphabet of \"es\""}, + {"rune":258,"result":"line 1, \"pala\u0102zz\", holds U+0102, which is not in the alphabet of \"es\""}, + {"rune":259,"result":"line 1, \"pala\u0103zz\", holds U+0103, which is not in the alphabet of \"es\""}, + {"rune":260,"result":"line 1, \"pala\u0104zz\", holds U+0104, which is not in the alphabet of \"es\""}, + {"rune":261,"result":"line 1, \"pala\u0105zz\", holds U+0105, which is not in the alphabet of \"es\""}, + {"rune":262,"result":"line 1, \"pala\u0106zz\", holds U+0106, which is not in the alphabet of \"es\""}, + {"rune":263,"result":"line 1, \"pala\u0107zz\", holds U+0107, which is not in the alphabet of \"es\""}, + {"rune":264,"result":"line 1, \"pala\u0108zz\", holds U+0108, which is not in the alphabet of \"es\""}, + {"rune":265,"result":"line 1, \"pala\u0109zz\", holds U+0109, which is not in the alphabet of \"es\""}, + {"rune":266,"result":"line 1, \"pala\u010azz\", holds U+010A, which is not in the alphabet of \"es\""}, + {"rune":267,"result":"line 1, \"pala\u010bzz\", holds U+010B, which is not in the alphabet of \"es\""}, + {"rune":268,"result":"line 1, \"pala\u010czz\", holds U+010C, which is not in the alphabet of \"es\""}, + {"rune":269,"result":"line 1, \"pala\u010dzz\", holds U+010D, which is not in the alphabet of \"es\""}, + {"rune":270,"result":"line 1, \"pala\u010ezz\", holds U+010E, which is not in the alphabet of \"es\""}, + {"rune":271,"result":"line 1, \"pala\u010fzz\", holds U+010F, which is not in the alphabet of \"es\""}, + {"rune":272,"result":"line 1, \"pala\u0110zz\", holds U+0110, which is not in the alphabet of \"es\""}, + {"rune":273,"result":"line 1, \"pala\u0111zz\", holds U+0111, which is not in the alphabet of \"es\""}, + {"rune":274,"result":"line 1, \"pala\u0112zz\", holds U+0112, which is not in the alphabet of \"es\""}, + {"rune":275,"result":"line 1, \"pala\u0113zz\", holds U+0113, which is not in the alphabet of \"es\""}, + {"rune":276,"result":"line 1, \"pala\u0114zz\", holds U+0114, which is not in the alphabet of \"es\""}, + {"rune":277,"result":"line 1, \"pala\u0115zz\", holds U+0115, which is not in the alphabet of \"es\""}, + {"rune":278,"result":"line 1, \"pala\u0116zz\", holds U+0116, which is not in the alphabet of \"es\""}, + {"rune":279,"result":"line 1, \"pala\u0117zz\", holds U+0117, which is not in the alphabet of \"es\""}, + {"rune":280,"result":"line 1, \"pala\u0118zz\", holds U+0118, which is not in the alphabet of \"es\""}, + {"rune":281,"result":"line 1, \"pala\u0119zz\", holds U+0119, which is not in the alphabet of \"es\""}, + {"rune":282,"result":"line 1, \"pala\u011azz\", holds U+011A, which is not in the alphabet of \"es\""}, + {"rune":283,"result":"line 1, \"pala\u011bzz\", holds U+011B, which is not in the alphabet of \"es\""}, + {"rune":284,"result":"line 1, \"pala\u011czz\", holds U+011C, which is not in the alphabet of \"es\""}, + {"rune":285,"result":"line 1, \"pala\u011dzz\", holds U+011D, which is not in the alphabet of \"es\""}, + {"rune":286,"result":"line 1, \"pala\u011ezz\", holds U+011E, which is not in the alphabet of \"es\""}, + {"rune":287,"result":"line 1, \"pala\u011fzz\", holds U+011F, which is not in the alphabet of \"es\""}, + {"rune":288,"result":"line 1, \"pala\u0120zz\", holds U+0120, which is not in the alphabet of \"es\""}, + {"rune":289,"result":"line 1, \"pala\u0121zz\", holds U+0121, which is not in the alphabet of \"es\""}, + {"rune":290,"result":"line 1, \"pala\u0122zz\", holds U+0122, which is not in the alphabet of \"es\""}, + {"rune":291,"result":"line 1, \"pala\u0123zz\", holds U+0123, which is not in the alphabet of \"es\""}, + {"rune":292,"result":"line 1, \"pala\u0124zz\", holds U+0124, which is not in the alphabet of \"es\""}, + {"rune":293,"result":"line 1, \"pala\u0125zz\", holds U+0125, which is not in the alphabet of \"es\""}, + {"rune":294,"result":"line 1, \"pala\u0126zz\", holds U+0126, which is not in the alphabet of \"es\""}, + {"rune":295,"result":"line 1, \"pala\u0127zz\", holds U+0127, which is not in the alphabet of \"es\""}, + {"rune":296,"result":"line 1, \"pala\u0128zz\", holds U+0128, which is not in the alphabet of \"es\""}, + {"rune":297,"result":"line 1, \"pala\u0129zz\", holds U+0129, which is not in the alphabet of \"es\""}, + {"rune":298,"result":"line 1, \"pala\u012azz\", holds U+012A, which is not in the alphabet of \"es\""}, + {"rune":299,"result":"line 1, \"pala\u012bzz\", holds U+012B, which is not in the alphabet of \"es\""}, + {"rune":300,"result":"line 1, \"pala\u012czz\", holds U+012C, which is not in the alphabet of \"es\""}, + {"rune":301,"result":"line 1, \"pala\u012dzz\", holds U+012D, which is not in the alphabet of \"es\""}, + {"rune":302,"result":"line 1, \"pala\u012ezz\", holds U+012E, which is not in the alphabet of \"es\""}, + {"rune":303,"result":"line 1, \"pala\u012fzz\", holds U+012F, which is not in the alphabet of \"es\""}, + {"rune":304,"result":"line 1, \"pala\u0130zz\", holds U+0130, which is not in the alphabet of \"es\""}, + {"rune":305,"result":"line 1, \"pala\u0131zz\", holds U+0131, which is not in the alphabet of \"es\""}, + {"rune":306,"result":"line 1, \"pala\u0132zz\", holds U+0132, which is not in the alphabet of \"es\""}, + {"rune":307,"result":"line 1, \"pala\u0133zz\", holds U+0133, which is not in the alphabet of \"es\""}, + {"rune":308,"result":"line 1, \"pala\u0134zz\", holds U+0134, which is not in the alphabet of \"es\""}, + {"rune":309,"result":"line 1, \"pala\u0135zz\", holds U+0135, which is not in the alphabet of \"es\""}, + {"rune":310,"result":"line 1, \"pala\u0136zz\", holds U+0136, which is not in the alphabet of \"es\""}, + {"rune":311,"result":"line 1, \"pala\u0137zz\", holds U+0137, which is not in the alphabet of \"es\""}, + {"rune":312,"result":"line 1, \"pala\u0138zz\", holds U+0138, which is not in the alphabet of \"es\""}, + {"rune":313,"result":"line 1, \"pala\u0139zz\", holds U+0139, which is not in the alphabet of \"es\""}, + {"rune":314,"result":"line 1, \"pala\u013azz\", holds U+013A, which is not in the alphabet of \"es\""}, + {"rune":315,"result":"line 1, \"pala\u013bzz\", holds U+013B, which is not in the alphabet of \"es\""}, + {"rune":316,"result":"line 1, \"pala\u013czz\", holds U+013C, which is not in the alphabet of \"es\""}, + {"rune":317,"result":"line 1, \"pala\u013dzz\", holds U+013D, which is not in the alphabet of \"es\""}, + {"rune":318,"result":"line 1, \"pala\u013ezz\", holds U+013E, which is not in the alphabet of \"es\""}, + {"rune":319,"result":"line 1, \"pala\u013fzz\", holds U+013F, which is not in the alphabet of \"es\""}, + {"rune":320,"result":"line 1, \"pala\u0140zz\", holds U+0140, which is not in the alphabet of \"es\""}, + {"rune":321,"result":"line 1, \"pala\u0141zz\", holds U+0141, which is not in the alphabet of \"es\""}, + {"rune":322,"result":"line 1, \"pala\u0142zz\", holds U+0142, which is not in the alphabet of \"es\""}, + {"rune":323,"result":"line 1, \"pala\u0143zz\", holds U+0143, which is not in the alphabet of \"es\""}, + {"rune":324,"result":"line 1, \"pala\u0144zz\", holds U+0144, which is not in the alphabet of \"es\""}, + {"rune":325,"result":"line 1, \"pala\u0145zz\", holds U+0145, which is not in the alphabet of \"es\""}, + {"rune":326,"result":"line 1, \"pala\u0146zz\", holds U+0146, which is not in the alphabet of \"es\""}, + {"rune":327,"result":"line 1, \"pala\u0147zz\", holds U+0147, which is not in the alphabet of \"es\""}, + {"rune":328,"result":"line 1, \"pala\u0148zz\", holds U+0148, which is not in the alphabet of \"es\""}, + {"rune":329,"result":"line 1, \"pala\u0149zz\", holds U+0149, which is not in the alphabet of \"es\""}, + {"rune":330,"result":"line 1, \"pala\u014azz\", holds U+014A, which is not in the alphabet of \"es\""}, + {"rune":331,"result":"line 1, \"pala\u014bzz\", holds U+014B, which is not in the alphabet of \"es\""}, + {"rune":332,"result":"line 1, \"pala\u014czz\", holds U+014C, which is not in the alphabet of \"es\""}, + {"rune":333,"result":"line 1, \"pala\u014dzz\", holds U+014D, which is not in the alphabet of \"es\""}, + {"rune":334,"result":"line 1, \"pala\u014ezz\", holds U+014E, which is not in the alphabet of \"es\""}, + {"rune":335,"result":"line 1, \"pala\u014fzz\", holds U+014F, which is not in the alphabet of \"es\""}, + {"rune":336,"result":"line 1, \"pala\u0150zz\", holds U+0150, which is not in the alphabet of \"es\""}, + {"rune":337,"result":"line 1, \"pala\u0151zz\", holds U+0151, which is not in the alphabet of \"es\""}, + {"rune":338,"result":"line 1, \"pala\u0152zz\", holds U+0152, which is not in the alphabet of \"es\""}, + {"rune":339,"result":"line 1, \"pala\u0153zz\", holds U+0153, which is not in the alphabet of \"es\""}, + {"rune":340,"result":"line 1, \"pala\u0154zz\", holds U+0154, which is not in the alphabet of \"es\""}, + {"rune":341,"result":"line 1, \"pala\u0155zz\", holds U+0155, which is not in the alphabet of \"es\""}, + {"rune":342,"result":"line 1, \"pala\u0156zz\", holds U+0156, which is not in the alphabet of \"es\""}, + {"rune":343,"result":"line 1, \"pala\u0157zz\", holds U+0157, which is not in the alphabet of \"es\""}, + {"rune":344,"result":"line 1, \"pala\u0158zz\", holds U+0158, which is not in the alphabet of \"es\""}, + {"rune":345,"result":"line 1, \"pala\u0159zz\", holds U+0159, which is not in the alphabet of \"es\""}, + {"rune":346,"result":"line 1, \"pala\u015azz\", holds U+015A, which is not in the alphabet of \"es\""}, + {"rune":347,"result":"line 1, \"pala\u015bzz\", holds U+015B, which is not in the alphabet of \"es\""}, + {"rune":348,"result":"line 1, \"pala\u015czz\", holds U+015C, which is not in the alphabet of \"es\""}, + {"rune":349,"result":"line 1, \"pala\u015dzz\", holds U+015D, which is not in the alphabet of \"es\""}, + {"rune":350,"result":"line 1, \"pala\u015ezz\", holds U+015E, which is not in the alphabet of \"es\""}, + {"rune":351,"result":"line 1, \"pala\u015fzz\", holds U+015F, which is not in the alphabet of \"es\""}, + {"rune":352,"result":"line 1, \"pala\u0160zz\", holds U+0160, which is not in the alphabet of \"es\""}, + {"rune":353,"result":"line 1, \"pala\u0161zz\", holds U+0161, which is not in the alphabet of \"es\""}, + {"rune":354,"result":"line 1, \"pala\u0162zz\", holds U+0162, which is not in the alphabet of \"es\""}, + {"rune":355,"result":"line 1, \"pala\u0163zz\", holds U+0163, which is not in the alphabet of \"es\""}, + {"rune":356,"result":"line 1, \"pala\u0164zz\", holds U+0164, which is not in the alphabet of \"es\""}, + {"rune":357,"result":"line 1, \"pala\u0165zz\", holds U+0165, which is not in the alphabet of \"es\""}, + {"rune":358,"result":"line 1, \"pala\u0166zz\", holds U+0166, which is not in the alphabet of \"es\""}, + {"rune":359,"result":"line 1, \"pala\u0167zz\", holds U+0167, which is not in the alphabet of \"es\""}, + {"rune":360,"result":"line 1, \"pala\u0168zz\", holds U+0168, which is not in the alphabet of \"es\""}, + {"rune":361,"result":"line 1, \"pala\u0169zz\", holds U+0169, which is not in the alphabet of \"es\""}, + {"rune":362,"result":"line 1, \"pala\u016azz\", holds U+016A, which is not in the alphabet of \"es\""}, + {"rune":363,"result":"line 1, \"pala\u016bzz\", holds U+016B, which is not in the alphabet of \"es\""}, + {"rune":364,"result":"line 1, \"pala\u016czz\", holds U+016C, which is not in the alphabet of \"es\""}, + {"rune":365,"result":"line 1, \"pala\u016dzz\", holds U+016D, which is not in the alphabet of \"es\""}, + {"rune":366,"result":"line 1, \"pala\u016ezz\", holds U+016E, which is not in the alphabet of \"es\""}, + {"rune":367,"result":"line 1, \"pala\u016fzz\", holds U+016F, which is not in the alphabet of \"es\""}, + {"rune":368,"result":"line 1, \"pala\u0170zz\", holds U+0170, which is not in the alphabet of \"es\""}, + {"rune":369,"result":"line 1, \"pala\u0171zz\", holds U+0171, which is not in the alphabet of \"es\""}, + {"rune":370,"result":"line 1, \"pala\u0172zz\", holds U+0172, which is not in the alphabet of \"es\""}, + {"rune":371,"result":"line 1, \"pala\u0173zz\", holds U+0173, which is not in the alphabet of \"es\""}, + {"rune":372,"result":"line 1, \"pala\u0174zz\", holds U+0174, which is not in the alphabet of \"es\""}, + {"rune":373,"result":"line 1, \"pala\u0175zz\", holds U+0175, which is not in the alphabet of \"es\""}, + {"rune":374,"result":"line 1, \"pala\u0176zz\", holds U+0176, which is not in the alphabet of \"es\""}, + {"rune":375,"result":"line 1, \"pala\u0177zz\", holds U+0177, which is not in the alphabet of \"es\""}, + {"rune":376,"result":"line 1, \"pala\u0178zz\", holds U+0178, which is not in the alphabet of \"es\""}, + {"rune":377,"result":"line 1, \"pala\u0179zz\", holds U+0179, which is not in the alphabet of \"es\""}, + {"rune":378,"result":"line 1, \"pala\u017azz\", holds U+017A, which is not in the alphabet of \"es\""}, + {"rune":379,"result":"line 1, \"pala\u017bzz\", holds U+017B, which is not in the alphabet of \"es\""}, + {"rune":380,"result":"line 1, \"pala\u017czz\", holds U+017C, which is not in the alphabet of \"es\""}, + {"rune":381,"result":"line 1, \"pala\u017dzz\", holds U+017D, which is not in the alphabet of \"es\""}, + {"rune":382,"result":"line 1, \"pala\u017ezz\", holds U+017E, which is not in the alphabet of \"es\""}, + {"rune":383,"result":"line 1, \"pala\u017fzz\", holds U+017F, which is not in the alphabet of \"es\""} + ], + "generate": [ + {"name":"6 words of the Spanish list","list":"es","size":7776,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate es 6"},"indices":[7552,321,1677,3637,3081,2378],"words":["vertebral","almirante","cojonudo","habla","ex\u00f3tico","diez"],"read":12,"next":"eb4e23cd"}, + {"name":"7 words of the Spanish list","list":"es","size":7776,"n":7,"stream":{"kind":"seeded","seed":"wordkey.Generate es 7"},"indices":[121,5143,3291,9,13,6590,1402],"words":["adecuado","obsequio","forzar","abejorro","abofetear","sargento","cava"],"read":14,"next":"15c97f0a"}, + {"name":"8 words of the Spanish list","list":"es","size":7776,"n":8,"stream":{"kind":"seeded","seed":"wordkey.Generate es 8"},"indices":[7419,3418,7185,4830,7558,168,7028,3097],"words":["usado","gamba","tobillo","mongol","vestidor","afeminado","tardanza","faja"],"read":16,"next":"c83ca329"}, + {"name":"12 words of the Spanish list","list":"es","size":7776,"n":12,"stream":{"kind":"seeded","seed":"wordkey.Generate es 12"},"indices":[3086,1561,5885,1894,7092,3918,7535,1859,3391,4059,7054,1332],"words":["fachada","cicatriz","prodigio","coqueta","tener","infancia","verbena","contable","f\u00f3sil","jaque","tejido","carn\u00edvoro"],"read":24,"next":"78624c9c"}, + {"name":"24 words of the Spanish list","list":"es","size":7776,"n":24,"stream":{"kind":"seeded","seed":"wordkey.Generate es 24"},"indices":[7726,1419,6867,1744,1845,923,7735,5731,4412,2730,924,7147,7166,2923,5612,5119,1213,4184,276,4448,5476,2429,7382,5994],"words":["zumo","cebolla","sport","comit\u00e9","consorcio","bestial","\u00e1mbito","polilla","l\u00f3gica","enigma","beta","tic","tinta","estafador","piedra","nutria","camerino","lat\u00edn","alc\u00e1ntara","magneto","pegar","dise\u00f1o","t\u00e1ctica","puzle"],"read":50,"next":"ce61e5db"}, + {"name":"6 words of the Spanish list, SHA-256 counter blocks","list":"es","size":7776,"n":6,"stream":{"kind":"counter","seed":"wordkey.Generate counter 6"},"indices":[1614,4473,6701,7267,3452,1442],"words":["claudia","maligno","setiembre","trasladar","gaveta","cenicero"],"read":14,"next":"4a80956b"}, + {"name":"7 words of the Spanish list, SHA-256 counter blocks","list":"es","size":7776,"n":7,"stream":{"kind":"counter","seed":"wordkey.Generate counter 7"},"indices":[6542,1450,4854,3563,2426,2781,6846],"words":["salom\u00f3n","centrado","mon\u00f3tono","green","disecci\u00f3n","episodio","soplete"],"read":16,"next":"144001d1"}, + {"name":"12 words of the Spanish list, SHA-256 counter blocks","list":"es","size":7776,"n":12,"stream":{"kind":"counter","seed":"wordkey.Generate counter 12"},"indices":[7021,5055,1483,6826,6779,4834,3251,7164,898,4404,5319,7648],"words":["tapete","niebla","chacal","soluci\u00f3n","sirope","mono","flotante","tim\u00f3n","beb\u00e9","l\u00e1tigo","palmera","vocero"],"read":26,"next":"425e314b"}, + {"name":"3888 words of the Spanish list, the most","list":"es","size":7776,"n":3888,"stream":{"kind":"seeded","seed":"wordkey.Generate es 3888"},"indices":[109,424,5504,6382,3300,4291,234,5711,1211,7623,2219,264,2945,2139,3937,3892,3125,1445,2447,1461,6236,3631,6501,1031,661,4190,4414,3315,5349,4693,5513,2640,5767,593,3379,4296,487,6785,5936,6207,2874,715,4666,2039,4752,2027,4686,1501,7394,934,1968,3500,532,6806,7676,4042,6953,140,21,5822,3739,590,6547,2660,7554,2937,1653,1015,2949,2179,2392,2349,300,5144,565,3975,4062,5844,2110,3162,1481,758,4106,7164,2165,5134,2914,1948,1752,5221,6008,2721,265,3260,783,6350,5561,6750,2801,1573,303,699,4586,4753,164,1315,7700,6338,2162,870,2331,7098,4309,3391,5657,6819,429,7698,1542,4508,3832,6466,6540,2591,3922,4470,3770,4193,2085,6164,6484,5744,841,4354,3698,2251,7256,5424,3148,6993,576,5004,160,7200,4102,4246,5436,2791,2968,521,6471,290,3538,922,3047,284,6051,335,5831,7589,132,1823,315,3724,2211,3488,5615,2159,7443,1239,7399,1216,6981,3680,4702,3471,5860,7134,6610,6875,6612,5330,918,2840,6768,1382,5131,5415,4885,6701,7386,3385,6983,4798,1104,4687,1611,4101,3521,4675,5996,2160,6633,98,7361,3753,385,6128,24,6183,3849,4347,1060,4075,4284,3016,2002,3475,431,5042,1850,604,6238,1558,1640,5698,4860,2539,374,5542,5136,5878,7172,3791,7511,7453,6039,3258,1578,7624,1909,6600,2453,6258,1255,4053,2209,85,1811,4684,2461,6041,6656,3275,1930,5359,3726,7147,862,1967,1224,3117,7376,5516,6711,2855,3314,3103,1374,914,6294,1940,4377,2468,6342,3845,6299,4523,3948,332,2974,2369,7303,1271,1586,5864,2616,1528,3382,6821,7398,2063,742,6861,2490,3108,319,4800,7419,6689,3659,2270,1588,2627,7101,236,4942,503,3859,5481,6917,376,415,4852,7703,229,5875,4832,2381,480,3782,4541,243,678,1636,2001,3263,3618,837,4987,5676,2283,2249,5977,6948,3685,4493,2609,6625,7364,3968,1582,1829,6156,3908,3588,1851,5129,2879,1905,7683,6157,4569,5554,6687,1728,7334,2347,6161,7632,5811,4488,7718,3543,669,3418,6003,1549,5534,1956,6065,3085,7467,548,66,5324,3386,3390,4384,3862,7451,5958,2662,4997,3666,1876,4945,3064,1412,3143,443,3930,7138,5566,6494,4689,3645,7318,3989,240,2713,4780,6388,4533,6491,4253,3478,3549,7442,3637,4412,7633,4585,5148,4700,3946,974,6666,6082,4883,1296,6313,6578,6319,71,409,6918,3575,7299,4581,6997,1267,1765,722,3055,6807,150,2008,212,6590,5185,4738,6191,4046,2956,4950,6492,2711,3116,1194,4469,485,1621,7143,100,4252,6880,7756,835,3400,6949,3912,2773,2465,4868,1854,2601,203,7073,4295,2338,625,5626,5345,2115,3191,3790,3045,2077,5555,3737,6759,1303,3470,4583,3182,4338,4490,5017,916,2106,2418,117,701,7320,2520,7149,6067,4634,1603,3848,2051,3367,1134,1757,5765,13,2295,5920,3164,3636,2820,1475,3353,4882,7002,5850,111,2679,3371,4467,7103,5500,1879,7689,7711,1628,490,2282,5075,7490,7521,4876,3747,1444,6461,3282,7472,65,6052,1276,931,1385,1706,2047,3006,3643,6327,7714,334,6831,4748,6969,4906,4460,5059,4812,1226,2310,2442,626,5640,3589,207,6867,643,611,5574,3453,906,1045,6838,2473,3857,4553,7040,6853,5927,6122,5243,3082,6980,3328,4992,6648,2527,5567,7310,5808,3421,7438,6261,2878,7449,5836,364,619,7759,7309,2100,23,327,1386,4009,1160,1952,5176,4982,6279,1534,4126,291,2606,4263,3038,5952,7238,5487,4165,5925,4650,7129,47,5834,5466,1861,3993,5523,4550,4095,1231,3866,423,6954,6425,3415,7296,5579,4334,7537,3149,6770,250,1275,2519,4939,6397,1436,2626,7416,4631,1651,1939,6010,4970,7479,4312,1237,7571,5892,151,5797,4557,804,1218,5088,4838,413,7405,4803,7527,3865,627,2311,5616,1359,3765,1815,4233,1957,7304,4676,5722,4747,3461,2862,7100,7210,4408,5778,5155,6296,2074,7535,5073,5713,7673,5116,2556,4418,800,6974,2733,7091,3351,4321,4639,378,6842,2993,5391,5140,248,360,197,3183,682,2141,3950,7434,2290,2798,4242,697,7461,7509,5874,1368,3509,4292,2574,2419,2337,3526,3591,6226,6698,5807,1472,5565,6034,5480,1172,339,2748,1022,4613,2569,575,2774,1184,219,4153,4603,7563,3594,4304,5180,5437,6670,7355,4833,375,6184,1245,3334,4311,2312,6510,5897,1460,5354,2098,5545,786,7315,6511,1565,1465,705,7342,4630,6566,7533,6371,1537,6102,7491,41,6518,329,1141,3793,34,3144,6874,3073,17,5665,5337,7013,693,7679,2863,4057,3921,3043,3978,6030,76,5478,2044,5686,5695,4481,749,1055,3494,6060,7666,4216,4705,2191,3370,5630,5085,867,4957,4893,3413,6013,1607,2390,894,902,596,2725,3605,4394,6668,2206,4925,3599,6014,3702,5333,5684,6241,4373,1564,2086,5076,2498,2587,4147,4177,1450,7613,233,3327,5041,3927,4345,3032,5520,3402,3741,114,4320,4528,3703,7316,5206,997,6607,7270,1714,5524,2823,4889,1772,718,7707,6175,7608,4211,3442,6796,1119,5228,5539,113,3563,2884,1020,5411,5195,460,5412,7721,255,2484,1801,1630,2281,6672,5413,1696,2864,1457,6155,3763,2049,761,1420,2782,4520,5434,6208,4482,380,4783,6481,2833,2156,2243,3279,5224,4823,4898,3063,5182,3388,5507,2151,3903,6802,33,7369,7671,6036,1212,952,4891,739,2787,4651,6541,6302,2691,3820,4462,3052,2837,1463,989,6703,252,738,582,7344,1177,2378,2644,5334,4845,3932,2105,7245,1142,5100,5647,6531,6892,5842,5358,7558,1100,7743,6817,5364,3035,2021,3906,4994,5403,6370,449,6205,1221,3467,4751,5329,258,2999,2488,4362,4781,7401,74,578,433,2015,1340,5749,4718,6017,2978,3827,2611,2582,1259,4539,4881,4212,505,5145,900,1342,2659,2873,2356,2749,5061,6603,5685,1487,980,7716,1540,3674,3295,1524,1308,6365,4695,1975,7124,7485,4138,4826,1002,2327,5517,7090,2005,1793,6822,5336,6502,5429,4888,7611,1366,1048,7,930,4213,4730,6635,2933,1227,4236,5087,3074,6306,4850,5351,4674,4886,3942,2789,1604,389,7590,4040,5441,4789,5809,2028,4270,1005,3312,3485,4239,2213,6678,6583,5757,6789,2637,5443,4415,1446,4616,6262,7619,1822,467,3175,4302,4959,3805,5051,5499,3558,1692,5450,7477,4921,6860,2360,6852,7421,547,5225,477,3203,1836,6810,2886,7486,7469,6702,7321,4656,6232,2836,1738,752,6320,3800,4900,5320,171,885,1712,5935,3967,6747,7353,119,2250,1821,458,4342,1265,7054,1713,1409,4922,6659,320,1974,2682,2560,1434,3152,4916,134,4169,1920,6047,832,6630,2252,4020,2672,3228,417,39,5921,741,2351,3409,5493,3982,1391,2925,5060,4363,7727,5276,1470,2506,6803,3850,6245,6340,4974,2812,5891,2374,6,1327,3433,5313,2695,7351,621,2947,2515,1699,5177,3596,949,5141,3915,5872,406,4112,3341,7182,7188,3893,3900,1400,5604,3964,7109,1010,6960,5506,2835,7545,6064,7523,1643,1383,6664,860,6856,7211,1583,1993,7664,4476,2797,763,7524,2760,1390,4355,7085,4851,6210,732,7106,2279,1074,1299,2200,1864,6004,6018,4917,2990,7076,856,6432,5570,5929,7725,2867,3796,6204,1927,4256,5406,4843,5306,2948,2154,1916,1533,1188,1734,3837,1432,2808,7044,4411,3114,4073,1672,1277,4204,3981,1152,5661,2838,2758,5190,2832,1778,6957,6708,4511,3140,1684,6225,7359,1396,4310,3102,5759,7088,4375,3717,459,1006,2687,4607,4856,3544,1157,748,1281,3939,4223,3248,6290,1090,5870,648,2788,122,5728,3366,3720,6265,404,311,180,950,6771,4679,7645,5846,811,7510,4995,5907,1885,5651,1658,2330,4214,3441,1454,3094,2091,5611,2014,2397,6287,4016,3246,3755,1792,757,7672,5149,309,7690,1176,4688,4024,2939,7300,6545,4473,3337,6301,5586,5771,6944,7670,1476,143,3208,6369,3905,4855,2704,5924,7237,1825,2654,1110,3159,61,6815,3230,5108,6615,5072,3120,5299,843,3472,3612,1345,1234,2980,6505,5050,2642,6936,986,3816,5079,6273,4307,179,3578,2481,7251,7312,3305,1928,2930,6325,7053,4107,616,1186,1376,2750,3510,891,1443,2404,2841,5821,6172,7110,3169,1095,5091,4143,4787,108,1328,833,4498,5158,7146,1828,1353,5703,7411,3487,3716,6457,5163,5274,712,5147,3624,6136,6913,667,7175,68,7668,2512,2699,5550,3567,5965,5893,6333,4039,2169,4417,6214,3896,6077,3910,1181,2735,2882,5553,910,5544,5990,4485,4867,3603,799,5982,3902,6926,3520,2380,5560,1004,4068,402,4779,4953,1880,2436,1235,6513,7555,4122,2304,6922,4790,2072,7724,6645,6192,659,326,3719,1538,4081,2092,2455,1516,5307,4791,1069,2857,1655,6079,6784,6665,7591,1127,6384,1462,4627,6876,4654,2146,6070,7647,1358,6312,6253,6616,4990,3532,958,3028,511,7352,7649,4966,3065,6781,7470,781,2824,2149,281,4659,5894,730,48,4059,5556,2425,6217,1441,5830,2558,3101,5477,3783,962,7221,2195,5667,7294,4976,4726,888,4804,6435,4986,6219,6358,6114,3974,5146,1964,3669,7552,22,7026,5895,4978,439,1225,5978,3794,4792,971,5995,773,289,6339,280,3369,384,6523,1102,2167,2631,3600,5887,5838,4721,776,4031,6268,1556,7746,2487,6490,313,4344,2216,3920,5666,5922,5253,7460,5583,1934,6611,3317,961,2895,2080,400,642,2071,1535,6111,817,3323,2595,1164,5972,1740,6123,6530,4963,6277,2303,2920,7441,2435,5171,4222,1452,4537,1862,2795,4331,7136,3734,7375,4934,472,5622,5687,1566,4514,2940,2434,2775,3799,7126,4294,2142,210,1729,4305,2217,4516,3679,794,1159,4186,2926,1092,4857,6676,1166,638,6453,3231,4620,3214,1936,855,610,4288,1099,3938,4757,3725,1292,7346,4005,4293,7423,2313,1105,6863,42,5905,4793,343,2291,1394,230,5918,6423,7140,1089,4078,2062,1198,2897,1840,4731,844,6576,158,5057,1455,7597,858,6081,7410,2826,298,6604,2178,6470,4647,2315,4737,5736,5376,1370,1490,3798,5271,2736,7075,5318,810,5829,4133,170,475,7701,3107,2491,7396,1293,2264,1990,5867,3580,6975,3706,1499,5327,6942,372,7033,5483,2652,1274,7030,2428,2403,6907,871,1904,3732,1760,1512,3595,2612,2751,5067,337,848,1923,7556,4788,3559,7202,1777,5092,1014,954,5720,4624,2908,2245,4357,363,927,2476,5796,4741,2183,5343,5518,2604,4740,1388,6012,6151,6637,274,4988,1249,6310,4360,3242,4711,1362,2097,2078,6240,1659,238,5634,2457,178,2357,3727,3977,249,7224,3217,7097,2546,6250,6601,6201,3151,5652,7517,5714,5063,3449,5682,3904,2082,3891,1622,4913,3803,6946,5962,5232,2087,7005,6525,4580,5940,5164,1096,1129,484,4097,3760,5785,6351,692,6938,3039,6564,5994,4742,395,6472,7768,7335,6392,7365,1679,7205,4910,1495,1477,237,6142,4472,1958,295,4552,50,3931,6859,1727,4879,4109,6521,3951,5814,7751,5758,2649,4834,5373,2143,829,6560,6915,499,939,2551,3630,3914,2084,254,6057,6069,2805,4451,7744,4391,5595,3359,3009,1348,6762,3663,3480,5746,2175,1593,294,1612,4734,7341,391,1191,273,3980,6710,204,4146,6733,1360,2767,6562,3984,1919,3723,6871,4839,6163,607,2739,1691,1794,2584,7212,3412,2566,4701,5826,2650,481,5649,5053,2344,1813,5847,795,6735,4590,6411,7081,3988,58,5438,7311,6274,6554,3965,7187,6509,2336,4108,3916,6199,3617,1222,7712,52,3041,7566,5008,1201,2987,5464,3389,7603,4380,3344,3623,3777,6767,2576,2239,5210,6386,2006,2203,6194,5896,2319,5973,3186,6643,566,2221,167,6346,6075,305,187,2096,4662,1781,4844,873,5598,6584,838,606,4010,7151,5573,6903,5247,4483,7534,2730,4544,4235,3268,7278,5382,6403,4173,1270,6200,5169,185,1398,5623,7745,4269,3291,5043,5889,5873,6093,2477,2424,543,1997,2921,1700,2517,2013,3235,6229,1887,719,5304,2450,600,188,5801,5569,3998,5396,2048,4164,6919,581,2847,7497,7208,5165,1371,4358,2371,60,2696,555,6450,3801,1855,2020,1725,4140,3807,5353,1063,4890,1209,3486,271,6877,7494,5671,899,6683,5262,156,1161,7658,3293,2596,3824,3007,5025,4353,3473,3342,5167,6368,31,1321,1253,1567,3632,7674,3625,411,1003,4364,4733,115,3606,5883,3026,6620,4908,4228,383,2229,5904,1258,3675,602,637,3395,4697,926,7049,4052,7642,6951,5525,2016,2233,3493,5196,4416,1316,1663,3180,7012,5981,2822,4548,1464,4386,2861,6950,662,5420,1966,7067,973,1471,4587,437,5882,595,4807,5668,572,6916,702,2088,4084,4438,346,6542,1214,1158,674,2059,969,3774,2202,6362,7225,853,2345,213,217,5251,5260,6366,6189,4145,4230,516,5726,3504,6104,306,6071,1354,703,5066,1914,1872,356,1557,7135,2671,6476,6854,4471,2829,847,2445,3448,3901,2308,3058,1996,5776,4119,5991,2653,6347,4350,4390,3761,1236,2641,897,1747,2125,2466,673,2181,3127,1195,4389,488,7752,3313,4313,6809,1405,4617,793,632,1553,4872,5930,4403,6058,6848,1062,3340,7287,7362,6776,2598,4999,923,5083,866,4606,2744,734,7389,4043,6088,157,1577,1751,6455,1107,707,1473,6016,5435,7319,7174,1947,6488,299,270,7601,6904,2024,1988,6549,7322,7001,3133,520,3362,1572,2471,4332,6405,4325,3077,3542,6264,1886,3249,3501,4610,442,1038,2677,2720,6098,6246,2800,6468,1816,6137,3830,2367,5693,647,338,5755,864,3551,6387,3604,5239,5805,5010,4750,235,7295,5241,2256,6650,1563,5495,3422,3810,5819,3292,2399,1594,1507,3638,5071,5708,1318,5126,2742,2079,6048,2227,1922,4478,4801,3373,6512,903,4894,95,2523,5964,1232,1910,4519,2707,5086,146,5183,2900,4853,6213,3483,6730,1896,358,2889,7448,2752,3088,557,4486,1208,4863,307,2129,4858,4340,7080,4500,2700,1680,5223,1350,1827,5881,4421,2814,5551,6911,1631,1965,3212,5459,3139,7446,118,3227,5348,2130,199,711,4468,3463,7595,4811,3221,4368,536,2502,3427,2522,2918,5370,6391,4300,3352,3976,5715,1749,1126,6126,4996,7573,4512,7261,552,4308,5273,7602,228,5754,3090,6622,5818,4125,6679,1912,6449,1042,2776,7726,441,4670,3145,6971,7480,3215,351,6778,2215,3506,427,6054,5751,6655,3346,2859,137,155,7468,4475,908,2148,5631,5026,5766,366,4197,174,2590,6837,2771,3771,3684,2451,6129,6519,1665,3647,4591,3945,3250,6504,1693,6056,2639,3176,7661,3072,2783,3577,892,2625,1602,3251,4786,6638,4369,2440,609,3247,5202,2225,5632,5980,5985,3841,2254,7526,3243,4619,6072,878,6244,3010,2755,1624,792,7695,2180,163,2842,6539,181,1889,453,3619,6958,1639,1779,5014,266,6961,5238,124,3852,3772,2793,6517,350,1581,7584,3136,457,6042,3015,7118,7550,2825,4082,5015,7617,2524,6573,2562,2236,7426,1960,432,5375,4100,2272,5512,4878,4405,5168,1085,6555,3194,3940,2719,5031,7289,6932,1401,911,1138,1998,6377,2301,4238,110,1294,779,6985,463,3642,6872,6260,7390,7153,5280,2214,6451,4531,1810,2715,6006,727,3655,6125,5256,7669,5584,7121,896,3550,1485,493,6846,3365,3283,7244,2843,3621,544,5816,620,1309,6352,4477,5621,7580,3229,987,1597,4864,2692,2332,4501,785,5385,5603,4713,483,4183,3683,1979,498,677,6984,5184,840,4004,5763,5729,868,6577,6032,1325,2255,5045,192,6900,1257,6402,1689,5717,990,764,7559,4392,7567,1759,1891,7343,5501,4618,1132,6356,1050,6269,4499,5541,2557,2647,3447,262,1087,6851,7366,1798,4185,2407,3959,5442,983,6447,277,7339,2747,5344,634,1981,3671,6121,7018,1175,2684,3909,3785,7228,5070,6247,2348,2683,2597,1830,1190,5710,5942,4006,3092,947,1796,6596,7229,6448,3876,1921,4061,193,3216,687,3780,2119,2176,1917,6372,1959,5917,6171,5643,1994,6429,5048,7373,3843,2766,4336,4257,3690,2373,6168,6167,7246,1890,6376,6135,2185,2449,6682,121,2765,3668,6906,6998,3196,2585,4535,3825,6395,5572,1333,3276,4371,4593,7635,2061,1329,1715,4349,4051,6777,6844,468,4442,1033,1330,2003,1008,2294,937,5277,3264,2846,3484,2134,7466,206,12,666,3219,1114,2664,5602,3712,5286,3048,2732,585,1970,6357,6798,4289,1415,3649,5077,4208,1101,915,7432,1286,5469,5770,2241,3296,5244,6736,5212,2503,6295,3535,1469,2985,6996,3696,1539,3953,7538,4244,6043,2737,6280,6394,6551,6308,7227,473,3168,3429,5762,147,6480,5909,2772,6738,5456,6552,959,613,5786,5379,1973,5249,4588,4685,1171,2057,7412,789,3934,4837,3867,617,5648,6452,1500,103,6050,7713,3593,5127,3302,5104,560,5054,6143,4314,5007,6419,7014,4919,5209,6022,1254,1187,7529,4545,1800,3952,2054,4505,6651,2989,6417,323,7723,5503,3210,3919,2757,102,4049,1666,5853,127,5377,6345,26,4361,1888,6007,1585,2828,4203,5044,2081,2464,577,3438,7197,6321,2000,3814,6727,322,172,4589,7093,2982,3851,2745,3135,6667,1644,7047,4029,4623,5124,774,440,4419,3458,292,5479,5105,7338,4290,54,7072,3236,4719,4526,4255,1873,7177,3602,7268,4496,285,6413,3160,5617,2663,5335,1849,782,5011,4622,5675,1016,6631,3514,6389,135,7715,2136,1719,412,5393,7084,1037,5285,4429,3660,6256,3869,3963,4930,4275,1430,5058,538,2548,3036,6031,4955,6341,1789,2177,1863,4998,2326,6826,4799,1780,2702,494,2284,5529,286,3564,5911,276,6743,1711,3947,2545,4459,7476,2205,3027,312,3819,1883,6329,2201,523,1215,2382,3877,352,1365,750,4725,6935,1197,1331,2064,4395,7425,399,2238,3657,3091,7562,2967,2116,4827,7428,3846,7065,2474,605,5993,4927,6401,7234,3797,3255,1841,884,1439,4708,2184,3670,6038,4262,3301,1804,165,5397,1185,4099,1183,5258,6715,3528,7418,1343,5690,4378,3749,6292,6626,963,1307,5153,4504,6443,7027,4652,1306,4706,6752,3527,1543,7305,7107,5614,6987,4562,25,1773,5900,6291,4664,1347,3424,1755,93,3579,189,6055,584,3019,5174,1838,5107,4784,3361,1943,3662,4151,4903,7201,106,3926,5974,509,5372,422,1068,4013,1875,2343,2511,2017,3190,2107,831,3583,770,7732,7653,7181,2354,2646,2101,5123,7191,4671,6086,7754,5890,5856,7381,1978,7568,2526,6757,2410,4117,6885,6878,5970,6235,78,7313,3460,696,2807,1244,2278,1525,1428,1284,3156,5752,1317,2958,1596,49,5750,561,1505,5473,6644,1283,865,209,3730,4629,7061,4722,3173,3997,7064,4805,5594,1435,1458,2370,6028,4144,6840,4139,3416,4542,6374,6332,1363,5125,182,6979,6407,4461,1335,6989,7459,3656,4060,1402,3821,4911,7696,6430,1018,1021,202,6756,2634,6572,173,7736,4441,1421,1168,4582,909,1903,7070,3533,2467,7263,7163,588,6706,4259,3834,2866,1824,6723,5848,7747,3199,7717,7242,6283,3479,5128,1900,4546,7332,901,4907,6782,7374,7496,2292,6808,3057,6254,6855,972,751,4873,6100,1178,3394,4869,635,1701,5851,344,3735,6700,3838,1131,5296,676,4383,6478,788,4703,2430,6558,6278,3523,7042,7478,3709,7388,6002,3943,501,2972,5957,1109,3089,1972,1145,3721,7167,7574,5312,44,6879,846,4699,4174,1447,2975,7482,5680,6380,4121,4131,3129,1788,448,6154,3056,6383,2815,7329,912,7230,7008,3818,3034,2849,4626,97,4058,5546,2708,6834,5861,6248,3795,4732,6145,6669,7709,4813,6629,3646,2675,5112,2531,5032,7593,1754,3571,2426,4330,6586,2636,4176,6436,2741,2334,4836,1367,724,5580,6754,5800,2138,3253,5024,1059,6734,524,7757,2769,675,3548,7499,83,5674,1146,6905,4028,1522,7219,4810,4547,40,1375,1541,478,86,735,1113,3240,1448,5999,4162,2022,3069,1379,3768,7737,4848,936,2810,1866,5399,1,2102,2306,5150,3574,53,2182,4319,5912,5837,1468,4014,3701,1941,2777,3298,541,1971,7333,7484,1301,7185,2501,2629,2962,5645,1150,3490,1081,6293,5360,4905,7677,5233,5961,2724,5137,5505,3597,814,5825,1618,6569,3652,1026,4356,803,3744,6931,4663,7055,5476,5723,5030,3357,1453,3232,790,3141,3119,4011,5266,3332,2350,3711,4968,4202,2581,6487,4167,5852,4036,2472,7433,3710,3970,382,3733,4495,5824,4179,563,3310,587,87,1991,4209,4283,1546,1942,1984,2123,6297,101,2952,5181,2919,559,3267,6947,6795,1902,7023,7247,1417,99,6920,5582,4806,7610,4575,586,545,5577,3154,5696,4215,3678,7349,232,3396,7604,1204,982,2505,6073,4093,149,2853,1647,7243,464,6732,2385,5532,7086,4032,2246,500,3005,2571,2263,398,7348,6581,651,1626,2785,4277,7372,145,2792,7207,784,1334,1399,1608,5069,62,4763,4560,2845,657,7582,6850,1683,263,4901,3537,7089,5172,94,7488,35,451,6398,3828,2901,1251,985,5721,371,1616,6196,4829,7692,7577,3842,4141,345,808,2875,6486,6223,5943,495,2555,4271,3607,7173,2153,4114,1238,4000,7513,6000,2928,2174,57,1698,4743,6203,2977,508,1848,618,3847,4985,599,5932,1295,2212,4435,3158,721,6422,7631,317,6901,5289,1575,3078,6415,769,7606,7570,7222,4166,7370,5854,7277,3831,4598,623,2147,5407,3304,3808,822,5764,4929,6062,6739,3534,7108,2365,7621,6181,5540,4372,6251,6704,5910,56,4980,4715,3840,1122,2909,81,5303,2463,368,6270,1662,1115,2912,407,3687,1632,527,314,2910,5653,2852,2694,2770,2986,2938,2618,6725,3222,4282,5633,283,851,2056,6314,5813,5650,4794,5309,1112,5862,3451,1802,4672,7032,3562,4592,1946,1758,630,1882,1220,1013,6661,6101,4577,2929,6497,1174,6887,731,1151,2406,759,2728,3012,6080,2379,3280,1047,3689,3465,3113,2670,2891,2567,46,2226,6288,3022,3075,4376,6178,907,1874,1642,4241,4324,3343,2856,3452,2955,3445,428,5449,7132,5094,38,4260,744,316,1377,948,5863,5902,5255,1041,297,7206,6475,2610,4887,3408,2293,7273,2045,1532,6773,1288,6992,1609,2248,3615,3759,2781,4281,624,4892,191,1937,6311,6112,5761,3197,84,1419,1560,5697,5725,614,1155,2802,4250,6495,5110,5173,4665,476,3874,4729,720,6536,381,3855,4182],"read":11238,"next":"552a164f"}, + {"name":"6 words of 12","size":12,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 12"},"indices":[4,11,8,9,7,5],"read":14,"next":"077eddf3"}, + {"name":"6 words of 13","size":13,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 13"},"indices":[5,6,4,3,2,11],"read":11,"next":"83aec74e"}, + {"name":"6 words of 16","size":16,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 16"},"indices":[11,3,10,15,7,8],"read":8,"next":"c189b683"}, + {"name":"6 words of 17","size":17,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 17"},"indices":[9,5,3,11,12,7],"read":9,"next":"b82b7743"}, + {"name":"6 words of 100","size":100,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 100"},"indices":[77,18,41,48,58,60],"read":8,"next":"976596b8"}, + {"name":"6 words of 255","size":255,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 255"},"indices":[179,162,55,253,133,126],"read":6,"next":"6c621f75"}, + {"name":"6 words of 256","size":256,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 256"},"indices":[42,59,184,44,21,16],"read":6,"next":"caa45192"}, + {"name":"6 words of 257","size":257,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 257"},"indices":[135,210,242,65,154,160],"read":26,"next":"c8778946"}, + {"name":"6 words of 2047","size":2047,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 2047"},"indices":[1427,667,604,2042,1632,1698],"read":12,"next":"12f5bd68"}, + {"name":"6 words of 2048","size":2048,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 2048"},"indices":[717,1383,705,229,1916,1660],"read":12,"next":"514e0658"}, + {"name":"6 words of 2049","size":2049,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 2049"},"indices":[1896,604,1955,1437,373,563],"read":16,"next":"1f552afe"}, + {"name":"6 words of 4096","size":4096,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 4096"},"indices":[3366,329,259,1101,997,1552],"read":12,"next":"ba4a07de"}, + {"name":"6 words of 7775","size":7775,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 7775"},"indices":[1556,5053,533,6292,2396,3983],"read":14,"next":"6d6f2e06"}, + {"name":"6 words of 7776","size":7776,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 7776"},"indices":[1522,1052,5366,4760,6603,6405],"read":14,"next":"1e028f83"}, + {"name":"6 words of 7777","size":7777,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 7777"},"indices":[4697,2832,2324,6110,1441,1088],"read":12,"next":"debd0218"}, + {"name":"6 words of 8192","size":8192,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 8192"},"indices":[5622,6365,2307,4380,6765,5885],"read":12,"next":"ed1fc6e1"}, + {"name":"6 words of 65535","size":65535,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 65535"},"indices":[52053,57393,60069,33726,7248,37022],"read":12,"next":"dfc89fd4"}, + {"name":"6 words of 65536","size":65536,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 65536"},"indices":[14606,12671,30058,2426,45855,20473],"read":12,"next":"dc5fb7c7"}, + {"name":"6 words of 65537","size":65537,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 65537"},"indices":[56692,4788,29478,53493,26980,44196],"read":36,"next":"26cd818c"}, + {"name":"6 words of 100000","size":100000,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 100000"},"indices":[69115,76031,73262,26566,2709,63951],"read":30,"next":"316abb7d"}, + {"name":"6 words of 1048577","size":1048577,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 1048577"},"indices":[900768,122124,269913,466370,711218,306573],"read":33,"next":"75d20cfa"}, + {"name":"12 words of 65537, SHA-256 counter blocks","size":65537,"n":12,"stream":{"kind":"counter","seed":"wordkey.Generate counter 65537"},"indices":[21932,33428,8290,57085,9183,17569,28618,21194,47511,49332,51193,58044],"read":66,"next":"2d2caf93"}, + {"name":"6 words of 12, the most","size":12,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 12 most"},"indices":[11,8,10,1,5,9],"read":13,"next":"191eb7eb"}, + {"name":"6 words of 13, the most","size":13,"n":6,"stream":{"kind":"seeded","seed":"wordkey.Generate 13 most"},"indices":[2,7,5,9,3,10],"read":10,"next":"2b27aedd"}, + {"name":"8 words of 17, the most","size":17,"n":8,"stream":{"kind":"seeded","seed":"wordkey.Generate 17 most"},"indices":[16,9,5,1,3,10,0,6],"read":14,"next":"9ddad546"}, + {"name":"50 words of 100, the most","size":100,"n":50,"stream":{"kind":"seeded","seed":"wordkey.Generate 100 most"},"indices":[51,40,75,85,11,44,62,23,8,92,0,34,55,89,31,94,39,60,18,45,74,27,98,57,69,12,1,54,59,20,67,4,7,10,41,52,9,38,63,19,32,68,16,17,43,28,33,21,99,24],"read":87,"next":"ff21a83a"}, + {"name":"the seed of TestGenerate: two indices only, then EOF","list":"es","size":7776,"n":6,"stream":{"kind":"bytes","hex":"0701c821","repeat":64},"read":256,"error":"wordkey: EOF"}, + {"name":"twelve bytes, six indices","list":"es","size":7776,"n":6,"stream":{"kind":"bytes","hex":"000000010002000300040005","repeat":1},"indices":[0,1,2,3,4,5],"words":["abad","abad\u00eda","abandonar","abandono","abanico","abarca"],"read":12}, + {"name":"8191 and 8032 drawn again, 0 drawn twice, 7775 the last index","list":"es","size":7776,"n":6,"stream":{"kind":"bytes","hex":"1fff00001f601e5f00000001000200030004","repeat":1},"indices":[0,7775,1,2,3,4],"words":["abad","\u00fatil","abad\u00eda","abandonar","abandono","abanico"],"read":18}, + {"name":"the three bits above the 13 of 7775 are cleared","list":"es","size":7776,"n":6,"stream":{"kind":"bytes","hex":"e000ffff21002200230024002500","repeat":1},"indices":[0,256,512,768,1024,1280],"words":["abad","alba\u00f1il","ap\u00e9ndice","azufre","bot\u00f3n","capitolio"],"read":14}, + {"name":"the bytes end inside a draw","list":"es","size":7776,"n":6,"stream":{"kind":"bytes","hex":"0000000100","repeat":1},"read":5,"error":"wordkey: unexpected EOF"}, + {"name":"no bytes","list":"es","size":7776,"n":6,"stream":{"kind":"bytes"},"read":0,"error":"wordkey: EOF"}, + {"name":"5 words of the Spanish list","list":"es","size":7776,"n":5,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: a key of words needs at least 6 words, not 5"}, + {"name":"0 words of the Spanish list","list":"es","size":7776,"n":0,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: a key of words needs at least 6 words, not 0"}, + {"name":"-1 words of the Spanish list","list":"es","size":7776,"n":-1,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: a key of words needs at least 6 words, not -1"}, + {"name":"3889 words of the Spanish list","list":"es","size":7776,"n":3889,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: 3889 words of a list of 7776"}, + {"name":"7776 words of the Spanish list","list":"es","size":7776,"n":7776,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: 7776 words of a list of 7776"}, + {"name":"6 words of 11","size":11,"n":6,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: 6 words of a list of 11"}, + {"name":"6 words of 0","size":0,"n":6,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: 6 words of a list of 0"}, + {"name":"5 words of 0","size":0,"n":5,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: a key of words needs at least 6 words, not 5"}, + {"name":"7 words of 12","size":12,"n":7,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: 7 words of a list of 12"}, + {"name":"7 words of 13","size":13,"n":7,"stream":{"kind":"seeded","seed":"never read"},"read":0,"error":"wordkey: 7 words of a list of 13"} + ], + "bits": [ + {"size":1,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":1,"count":1,"bits":"0","hex":"0000000000000000"}, + {"size":1,"count":2,"bits":"-Inf","hex":"fff0000000000000"}, + {"size":1,"count":6,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":1,"count":7,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":1,"count":8,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":1,"count":12,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":2,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":2,"count":1,"bits":"1","hex":"3ff0000000000000"}, + {"size":2,"count":2,"bits":"1","hex":"3ff0000000000000"}, + {"size":2,"count":6,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":2,"count":7,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":2,"count":8,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":2,"count":12,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":3,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":3,"count":1,"bits":"1.5849625007211563","hex":"3ff95c01a39fbd69"}, + {"size":3,"count":2,"bits":"2.584962500721156","hex":"4004ae00d1cfdeb4"}, + {"size":3,"count":6,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":3,"count":7,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":3,"count":8,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":3,"count":12,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":5,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":5,"count":1,"bits":"2.321928094887362","hex":"4002934f0979a371"}, + {"size":5,"count":2,"bits":"4.321928094887362","hex":"401149a784bcd1b8"}, + {"size":5,"count":6,"bits":"-Inf","hex":"fff0000000000000"}, + {"size":5,"count":7,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":5,"count":8,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":5,"count":12,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":12,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":12,"count":1,"bits":"3.584962500721156","hex":"400cae00d1cfdeb4"}, + {"size":12,"count":2,"bits":"7.044394119358453","hex":"401c2d75a6eb1dfb"}, + {"size":12,"count":6,"bits":"19.343602137745734","hex":"403357f64f487420"}, + {"size":12,"count":7,"bits":"21.928564638466888","hex":"4035edb669826ff6"}, + {"size":12,"count":8,"bits":"24.25049273335425","hex":"403840204ab1a464"}, + {"size":12,"count":12,"bits":"28.835455234075408","hex":"403cd5e064eba03b"}, + {"size":13,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":13,"count":1,"bits":"3.700439718141092","hex":"400d9a802391e233"}, + {"size":13,"count":2,"bits":"7.285402218862249","hex":"401d24407ab0e074"}, + {"size":13,"count":6,"bits":"20.23668693382922","hex":"40343c9783d02fe0"}, + {"size":13,"count":7,"bits":"23.044041855886825","hex":"40370b4653bab066"}, + {"size":13,"count":8,"bits":"25.62900435660798","hex":"4039a1066df4ac3c"}, + {"size":13,"count":12,"bits":"32.535894952216495","hex":"4040449834aeee40"}, + {"size":100,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":100,"count":1,"bits":"6.643856189774724","hex":"401a934f0979a371"}, + {"size":100,"count":2,"bits":"13.273212809854334","hex":"402a8be28ca65863"}, + {"size":100,"count":6,"bits":"39.64265360520877","hex":"4043d242792c839b"}, + {"size":100,"count":7,"bits":"46.19724245688641","hex":"4047193f3da6dadb"}, + {"size":100,"count":8,"bits":"52.73640126799444","hex":"404a5e4265916270"}, + {"size":100,"count":12,"bits":"78.73534439154622","hex":"4053af0fe1ec3f3c"}, + {"size":255,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":255,"count":1,"bits":"7.994353436858858","hex":"401ffa37c98fe55f"}, + {"size":255,"count":2,"bits":"15.983038123631022","hex":"402ff750c5df6ed2"}, + {"size":255,"count":6,"bits":"47.880639460438104","hex":"4047f0b8cb39130a"}, + {"size":255,"count":7,"bits":"55.840641392506186","hex":"404beb9a231c3d2e"}, + {"size":255,"count":8,"bits":"63.79483770289306","hex":"404fe5bd3de9c6d8"}, + {"size":255,"count":12,"bits":"95.55309471638243","hex":"4057e365e7619cfd"}, + {"size":256,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":256,"count":1,"bits":"8","hex":"4020000000000000"}, + {"size":256,"count":2,"bits":"15.994353436858859","hex":"402ffd1be4c7f2b0"}, + {"size":256,"count":6,"bits":"47.914855175776026","hex":"4047f519f9724466"}, + {"size":256,"count":7,"bits":"55.88063946043811","hex":"404bf0b8cb39130b"}, + {"size":256,"count":8,"bits":"63.84064139250619","hex":"404feb9a231c3d2f"}, + {"size":256,"count":12,"bits":"95.62235737881954","hex":"4057e7d4b40b1d12"}, + {"size":257,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":257,"count":1,"bits":"8.005624549193879","hex":"402002e1388daf56"}, + {"size":257,"count":2,"bits":"16.00562454919388","hex":"403001709c46d7ab"}, + {"size":257,"count":6,"bits":"47.94893617101913","hex":"4047f976bd8e4262"}, + {"size":257,"count":7,"bits":"55.9204797249699","hex":"404bf5d24795b03b"}, + {"size":257,"count":8,"bits":"63.88626400963199","hex":"404ff171195c7ee0"}, + {"size":257,"count":12,"bits":"95.69134398901087","hex":"4057ec3efadbc5a0"}, + {"size":2047,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":2047,"count":1,"bits":"10.99929538702341","hex":"4025ffa3a51c9e51"}, + {"size":2047,"count":2,"bits":"21.99788581676874","hex":"4035ff7571e429fb"}, + {"size":2047,"count":6,"bits":"65.9851910651465","hex":"40507f0d5ed34766"}, + {"size":2047,"count":7,"bits":"76.98025153217921","hex":"40533ebc70ec2412"}, + {"size":2047,"count":8,"bits":"87.97460496903807","hex":"4055fe5fed852268"}, + {"size":2047,"count":12,"bits":"131.94494147626207","hex":"40607e3cf5e825bf"}, + {"size":2048,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":2048,"count":1,"bits":"11","hex":"4026000000000000"}, + {"size":2048,"count":2,"bits":"21.99929538702341","hex":"4035ffd1d28e4f28"}, + {"size":2048,"count":6,"bits":"65.9894239142687","hex":"40507f52b8ae6a85"}, + {"size":2048,"count":7,"bits":"76.9851910651465","hex":"40533f0d5ed34766"}, + {"size":2048,"count":8,"bits":"87.98025153217921","hex":"4055febc70ec2412"}, + {"size":2048,"count":12,"bits":"131.95341963018637","hex":"40607e8269e2607a"}, + {"size":2049,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":2049,"count":1,"bits":"11.000704269011246","hex":"4026005c4f58bde5"}, + {"size":2049,"count":2,"bits":"22.000704269011244","hex":"4036002e27ac5ef2"}, + {"size":2049,"count":6,"bits":"65.9936546945467","hex":"40507f9809dc2614"}, + {"size":2049,"count":7,"bits":"76.99012818327994","hex":"40533f5e42998241"}, + {"size":2049,"count":8,"bits":"87.98589533415773","hex":"4055ff18e8be5f22"}, + {"size":2049,"count":12,"bits":"131.96189363423173","hex":"40607ec7d528a830"}, + {"size":4096,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":4096,"count":1,"bits":"12","hex":"4028000000000000"}, + {"size":4096,"count":2,"bits":"23.99964773652837","hex":"4037ffe8e9ffe8e7"}, + {"size":4096,"count":6,"bits":"71.99471432662824","hex":"4051ffa966476ec8"}, + {"size":4096,"count":7,"bits":"83.99259945445735","hex":"4054ff86bfdcbafe"}, + {"size":4096,"count":8,"bits":"95.99013180198372","hex":"4057ff5e51c70ffa"}, + {"size":4096,"count":12,"bits":"143.97673166270826","hex":"4061ff4162c28997"}, + {"size":7775,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":7775,"count":1,"bits":"12.924626959905327","hex":"4029d968b4739629"}, + {"size":7775,"count":2,"bits":"25.849068352244522","hex":"4039d95c8b24f576"}, + {"size":7775,"count":6,"bits":"77.54497776841153","hex":"405362e0ea6f17f9"}, + {"size":7775,"count":7,"bits":"90.46849096471993","hex":"40569dfbc186fc64"}, + {"size":7775,"count":8,"bits":"103.39181845013913","hex":"4059d9138db15449"}, + {"size":7775,"count":12,"bits":"155.0832708046572","hex":"406362aa2788d6db"}, + {"size":7776,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":7776,"count":1,"bits":"12.92481250360578","hex":"4029d9810643d661"}, + {"size":7776,"count":2,"bits":"25.849439463511107","hex":"4039d974dd5bb645"}, + {"size":7776,"count":6,"bits":"77.54609138872225","hex":"405362f3294bcc1d"}, + {"size":7776,"count":7,"bits":"90.46979027201732","hex":"40569e110b3792c6"}, + {"size":7776,"count":8,"bits":"103.39330346832573","hex":"4059d92be24f7731"}, + {"size":7776,"count":12,"bits":"155.08549890554931","hex":"406362bc683365b3"}, + {"size":7777,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":7777,"count":1,"bits":"12.924998023446696","hex":"4029d999574722eb"}, + {"size":7777,"count":2,"bits":"25.849810527052476","hex":"4039d98d2ec57ca6"}, + {"size":7777,"count":6,"bits":"77.5472048657836","hex":"40536305678eb02b"}, + {"size":7777,"count":7,"bits":"90.47108941216894","hex":"40569e265434b07a"}, + {"size":7777,"count":8,"bits":"103.39478829546401","hex":"4059d94436207723"}, + {"size":7777,"count":12,"bits":"155.08772671972133","hex":"406362cea8440608"}, + {"size":8192,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":8192,"count":1,"bits":"13","hex":"402a000000000000"}, + {"size":8192,"count":2,"bits":"25.999823879015725","hex":"4039fff4752e21e5"}, + {"size":8192,"count":6,"bits":"77.99735775509549","hex":"40537fd4b59f2304"}, + {"size":8192,"count":7,"bits":"90.99630070653858","hex":"4056bfc36409e427"}, + {"size":8192,"count":8,"bits":"103.9950674079001","hex":"4059ffaf2f358fc5"}, + {"size":8192,"count":12,"bits":"155.98837128175916","hex":"40637fa0bccf6ec2"}, + {"size":10000,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":10000,"count":1,"bits":"13.287712379549449","hex":"402a934f0979a371"}, + {"size":10000,"count":2,"bits":"26.575280482380855","hex":"403a934594e9da56"}, + {"size":10000,"count":6,"bits":"79.72410983788599","hex":"4053ee57d0ca1ba9"}, + {"size":10000,"count":7,"bits":"93.01095634062187","hex":"405740b3823929e8"}, + {"size":10000,"count":8,"bits":"106.29765848001738","hex":"405a930cd627434f"}, + {"size":10000,"count":12,"bits":"159.4430231152088","hex":"4063ee2d3ecfe634"}, + {"size":65535,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":65535,"count":1,"bits":"15.999977986052736","hex":"402ffffd1d55a205"}, + {"size":65535,"count":2,"bits":"31.999933957822293","hex":"403ffffbabff01b0"}, + {"size":65535,"count":6,"bits":"95.99953769535011","hex":"4057fff86cf42978"}, + {"size":65535,"count":7,"bits":"111.99938359066472","hex":"405bfff5e6978419"}, + {"size":65535,"count":8,"bits":"127.99920746968044","hex":"405ffff303e30c92"}, + {"size":65535,"count":12,"bits":"191.9982828160347","hex":"4067fff1eecde0e4"}, + {"size":65536,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":65536,"count":1,"bits":"16","hex":"4030000000000000"}, + {"size":65536,"count":2,"bits":"31.999977986052734","hex":"403ffffe8eaad102"}, + {"size":65536,"count":6,"bits":"95.99966978407262","hex":"4057fffa96f9590b"}, + {"size":65536,"count":7,"bits":"111.99953769535013","hex":"405bfff86cf42979"}, + {"size":65536,"count":8,"bits":"127.99938359066473","hex":"405ffff5e697841a"}, + {"size":65536,"count":12,"bits":"191.9985470055745","hex":"4067fff418d98ec2"}, + {"size":65537,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":65537,"count":1,"bits":"16.00002201361136","hex":"403000017153bda9"}, + {"size":65537,"count":2,"bits":"32.00002201361136","hex":"40400000b8a9ded4"}, + {"size":65537,"count":6,"bits":"95.99980187077954","hex":"4057fffcc0fc5e93"}, + {"size":65537,"count":7,"bits":"111.99969179768398","hex":"405bfffaf34e4875"}, + {"size":65537,"count":8,"bits":"127.99955970896148","hex":"405ffff8c94918e3"}, + {"size":65537,"count":12,"bits":"191.9988111910827","hex":"4067fff642e31287"}, + {"size":1048576,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":1048576,"count":1,"bits":"20","hex":"4034000000000000"}, + {"size":1048576,"count":2,"bits":"39.99999862413814","hex":"4043fffff4755bf1"}, + {"size":1048576,"count":6,"bits":"119.99997936204582","hex":"405dffffa9702a5a"}, + {"size":1048576,"count":7,"bits":"139.99997110685496","hex":"40617fffc3681c62"}, + {"size":1048576,"count":8,"bits":"159.99996147579435","hex":"4063ffffaf35797e"}, + {"size":1048576,"count":12,"bits":"239.99990919282837","hex":"406dffff4190455d"}, + {"size":2147483647,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":2147483647,"count":1,"bits":"30.999999999328193","hex":"403efffffffd1d57"}, + {"size":2147483647,"count":2,"bits":"61.999999997984574","hex":"404efffffffbac02"}, + {"size":2147483647,"count":6,"bits":"185.99999998589203","hex":"40673ffffff86d04"}, + {"size":2147483647,"count":7,"bits":"216.99999998118938","hex":"406b1ffffff5e6b0"}, + {"size":2147483647,"count":8,"bits":"247.99999997581492","hex":"406efffffff30407"}, + {"size":2147483647,"count":12,"bits":"371.99999994759895","hex":"40773ffffff1ef07"}, + {"size":2147483648,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":2147483648,"count":1,"bits":"31","hex":"403f000000000000"}, + {"size":2147483648,"count":2,"bits":"61.999999999328196","hex":"404efffffffe8eac"}, + {"size":2147483648,"count":6,"bits":"185.99999998992288","hex":"40673ffffffa9703"}, + {"size":2147483648,"count":7,"bits":"216.99999998589203","hex":"406b1ffffff86d04"}, + {"size":2147483648,"count":8,"bits":"247.99999998118938","hex":"406efffffff5e6b0"}, + {"size":2147483648,"count":12,"bits":"371.9999999556607","hex":"40773ffffff41907"}, + {"size":4294967295,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":4294967295,"count":1,"bits":"31.999999999664098","hex":"403ffffffffe8eac"}, + {"size":4294967295,"count":2,"bits":"63.999999998992294","hex":"404ffffffffdd602"}, + {"size":4294967295,"count":6,"bits":"191.99999999294604","hex":"4067fffffffc3683"}, + {"size":4294967295,"count":7,"bits":"223.99999999059472","hex":"406bfffffffaf359"}, + {"size":4294967295,"count":8,"bits":"255.99999998790747","hex":"406ffffffff98204"}, + {"size":4294967295,"count":12,"bits":"383.9999999737995","hex":"4077fffffff8f784"}, + {"size":4294967296,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":4294967296,"count":1,"bits":"32","hex":"4040000000000000"}, + {"size":4294967296,"count":2,"bits":"63.9999999996641","hex":"404fffffffff4756"}, + {"size":4294967296,"count":6,"bits":"191.99999999496146","hex":"4067fffffffd4b82"}, + {"size":4294967296,"count":7,"bits":"223.99999999294604","hex":"406bfffffffc3683"}, + {"size":4294967296,"count":8,"bits":"255.99999999059472","hex":"406ffffffffaf359"}, + {"size":4294967296,"count":12,"bits":"383.9999999778303","hex":"4077fffffffa0c83"}, + {"size":4294967297,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":4294967297,"count":1,"bits":"32.0000000003359","hex":"404000000000b8aa"}, + {"size":4294967297,"count":2,"bits":"64.0000000003359","hex":"4050000000005c55"}, + {"size":4294967297,"count":6,"bits":"191.99999999697687","hex":"4067fffffffe6081"}, + {"size":4294967297,"count":7,"bits":"223.99999999529734","hex":"406bfffffffd79ac"}, + {"size":4294967297,"count":8,"bits":"255.99999999328193","hex":"406ffffffffc64ad"}, + {"size":4294967297,"count":12,"bits":"383.9999999818612","hex":"4077fffffffb2183"}, + {"size":4503599627370497,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":4503599627370497,"count":1,"bits":"52","hex":"404a000000000000"}, + {"size":4503599627370497,"count":2,"bits":"104","hex":"405a000000000000"}, + {"size":4503599627370497,"count":6,"bits":"312","hex":"4073800000000000"}, + {"size":4503599627370497,"count":7,"bits":"364","hex":"4076c00000000000"}, + {"size":4503599627370497,"count":8,"bits":"416","hex":"407a000000000000"}, + {"size":4503599627370497,"count":12,"bits":"624","hex":"4083800000000000"}, + {"size":9007199254740991,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":9007199254740991,"count":1,"bits":"53","hex":"404a800000000000"}, + {"size":9007199254740991,"count":2,"bits":"106","hex":"405a800000000000"}, + {"size":9007199254740991,"count":6,"bits":"318","hex":"4073e00000000000"}, + {"size":9007199254740991,"count":7,"bits":"371","hex":"4077300000000000"}, + {"size":9007199254740991,"count":8,"bits":"424","hex":"407a800000000000"}, + {"size":9007199254740991,"count":12,"bits":"636","hex":"4083e00000000000"}, + {"size":9007199254740992,"count":0,"bits":"0","hex":"0000000000000000"}, + {"size":9007199254740992,"count":1,"bits":"53","hex":"404a800000000000"}, + {"size":9007199254740992,"count":2,"bits":"106","hex":"405a800000000000"}, + {"size":9007199254740992,"count":6,"bits":"318","hex":"4073e00000000000"}, + {"size":9007199254740992,"count":7,"bits":"371","hex":"4077300000000000"}, + {"size":9007199254740992,"count":8,"bits":"424","hex":"407a800000000000"}, + {"size":9007199254740992,"count":12,"bits":"636","hex":"4083e00000000000"}, + {"size":0,"count":1,"bits":"-Inf","hex":"fff0000000000000"}, + {"size":-1,"count":1,"bits":"NaN","hex":"7ff8000000000001"}, + {"size":7776,"count":-1,"bits":"0","hex":"0000000000000000"}, + {"size":0,"count":0,"bits":"0","hex":"0000000000000000"} + ], + "bits_digests": [ + {"name":"one word of 1 to 65536: the log2 of Go","sizes":[1,65536],"counts":[1,1],"sha256":"54467d69cce12574b891110ee6b74c2e426a833a51ea3df003c7658cfa3ab6de"}, + {"name":"6 to 8 words of 2048 to 10000","sizes":[2048,10000],"counts":[6,8],"sha256":"9e055008813b6d2ec5b9477a777c44d30d650134cd890eeb679552403297332e"}, + {"name":"0 to 600 words of 7776","sizes":[7776,7776],"counts":[0,600],"sha256":"b6e756155be0121f6db294a47b3dbb947652cc931fb078f1db5a9e39643c905a"}, + {"name":"1 word of 2^32 - 4096 to 2^32 + 4096","sizes":[4294963200,4294971392],"counts":[1,1],"sha256":"a95430f39eda0ef2865e11d1b92c8b0e604e4a9387ac881905d77af880240d2d"} + ] +} diff --git a/test/wordlist_support.dart b/test/wordlist_support.dart new file mode 100644 index 0000000..740c5b8 --- /dev/null +++ b/test/wordlist_support.dart @@ -0,0 +1,168 @@ +// Helpers of the tests of the word lists: the base list of TestCheckList of +// Go and its edits, as test/vectors/wordlist_vectors.json writes them; a +// list of words that are their indices; and the random sources of the +// vectors of Generate. They read no file. + +import 'dart:collection'; +import 'dart:typed_data'; + +import 'package:datekeys/src/bytes.dart'; +import 'package:datekeys/src/random.dart'; +import 'package:datekeys/src/sha256.dart'; +import 'package:datekeys/src/wordkey.dart' show WordKeyException; + +typedef Json = Map; + +/// "ok", or the message of the [WordKeyException] that [f] throws. +String outcome(void Function() f) { + try { + f(); + return 'ok'; + } on WordKeyException catch (e) { + return e.message; + } +} + +/// Word [i] of the base list of TestCheckList: "pal" and three letters, +/// palaaa, palaab, …, up to i = 17 575, palzzz. +String baseWord(int i) { + final letters = [i ~/ 676, i ~/ 26 % 26, i % 26]; + return 'pal${String.fromCharCodes([for (final l in letters) 0x61 + l])}'; +} + +/// The words of a case of the vectors, as bytes: the first `size` words of +/// the base list, the word of each edit of `set` at its index, and the +/// words of `append` after them. +List caseWords(Json c) { + final words = [ + for (var i = 0; i < (c['size']! as int); i++) utf8Bytes(baseWord(i)), + ]; + for (final e in (c['set'] as List? ?? const []).cast()) { + words[e['at']! as int] = fromHex(e['word']! as String); + } + for (final w in (c['append'] as List? ?? const []).cast()) { + words.add(fromHex(w)); + } + return words; +} + +/// [parts] joined by [separator]. +Uint8List joinBytes(List> parts, List separator) => concatBytes([ + for (var i = 0; i < parts.length; i++) ...[if (i > 0) separator, parts[i]], +]); + +/// [bytes] repeated [count] times, as Go's bytes.Repeat. +Uint8List repeatBytes(List bytes, int count) => + concatBytes([for (var i = 0; i < count; i++) bytes]); + +/// The 64 bits of [x], big-endian, in hexadecimal: Go's +/// `%016x` of math.Float64bits. +String doubleHex(double x) => + toHex(Uint8List.sublistView(ByteData(8)..setFloat64(0, x))); + +/// The double of the 64 bits [hex]. +double hexDouble(String hex) => + ByteData.sublistView(fromHex(hex)).getFloat64(0); + +/// The words "0", "1", …, one less than [length]: a list whose words are +/// their indices, without storing them. generateWords reads only its length +/// and the words it draws. +final class IndexWords extends ListBase { + IndexWords(this._length); + + final int _length; + + @override + int get length => _length; + + @override + set length(int _) => throw UnsupportedError('a fixed length'); + + @override + String operator [](int i) { + RangeError.checkValidIndex(i, this); + return '$i'; + } + + @override + void operator []=(int i, String value) => + throw UnsupportedError('an unmodifiable list'); +} + +/// A source that counts the bytes that another one gives. +final class CountingSource implements RandomSource { + CountingSource(this._inner); + + final RandomSource _inner; + + /// The bytes given so far. + int read = 0; + + @override + void fill(Uint8List out) { + _inner.fill(out); + read += out.length; + } +} + +/// The bytes of [bytes], then nothing: a fill past them gives nothing and +/// throws a [StateError], where Go's io.Reader gives io.EOF, or the bytes +/// left and io.ErrUnexpectedEOF. +final class ReplaySource implements RandomSource { + ReplaySource(List bytes) : _bytes = Uint8List.fromList(bytes); + + final Uint8List _bytes; + int _at = 0; + + @override + void fill(Uint8List out) { + if (_at + out.length > _bytes.length) throw StateError('no more bytes'); + out.setRange(0, out.length, _bytes, _at); + _at += out.length; + } +} + +/// SHA-256 of [label] and a 32-bit big-endian counter from 0, block after +/// block: the counter stream of the vectors. +final class CounterSource implements RandomSource { + CounterSource(List label) : _label = Uint8List.fromList(label); + + final Uint8List _label; + int _counter = 0; + Uint8List _block = Uint8List(0); + int _at = 0; + + @override + void fill(Uint8List out) { + for (var n = 0; n < out.length;) { + if (_at == _block.length) { + final input = Uint8List(_label.length + 4)..setAll(0, _label); + ByteData.sublistView(input).setUint32(_label.length, _counter++); + _block = sha256(input); + _at = 0; + } + final k = out.length - n < _block.length - _at + ? out.length - n + : _block.length - _at; + out.setRange(n, n + k, _block, _at); + n += k; + _at += k; + } + } +} + +/// The source of the stream of a case of generate: `seeded`, the keystream +/// of [SeededRandomSource] of the seed; `counter`, a [CounterSource] of the +/// label; `bytes`, hex repeated `repeat` times, a [ReplaySource]. +RandomSource streamOf(Json s) => switch (s['kind']) { + 'seeded' => SeededRandomSource(utf8Bytes(s['seed']! as String)), + 'counter' => CounterSource(utf8Bytes(s['seed']! as String)), + 'bytes' => ReplaySource( + repeatBytes(fromHex(s['hex'] as String? ?? ''), s['repeat'] as int? ?? 0), + ), + final kind => throw ArgumentError.value(kind, 'kind'), +}; + +/// The bytes that crypto/rand.Int reads for each draw of an index below +/// [size]: those of size − 1. +int drawSize(int size) => ((size - 1).bitLength + 7) ~/ 8; diff --git a/test/wordlist_test.dart b/test/wordlist_test.dart new file mode 100644 index 0000000..b6763fa --- /dev/null +++ b/test/wordlist_test.dart @@ -0,0 +1,341 @@ +// The word lists of the key of words (spec §38.1) against +// test/vectors/wordlist_vectors.json, whose expected values the Go reference +// computed (tool/wordlist_go_vectors.go): the constants and the pinned +// lists; the text of a list read as wordkey.List reads it; wordkey.CheckList +// with its texts, also on each code point up to U+017F; the words that +// wordkey.Generate draws from the same bytes; and wordkey.Bits, bit for bit. +// And the cases of TestCheckList, TestGenerate and TestBits of Go, as Go +// writes them. The vectors come from a Dart constant, so that these tests +// also run compiled to JavaScript; the Spanish list, the CSPRNG of the +// platform and the alphabet of every code point are in wordlist_vm_test.dart. + +import 'dart:convert'; +import 'dart:math' as math; +import 'dart:typed_data'; + +import 'package:datekeys/src/bytes.dart'; +import 'package:datekeys/src/pathrule.dart' show codePointName; +import 'package:datekeys/src/random.dart'; +import 'package:datekeys/src/sha256.dart'; +import 'package:datekeys/src/wordkey.dart'; +import 'package:datekeys/src/wordlist.dart'; +import 'package:test/test.dart'; + +import 'random_support.dart' show seeded; +import 'vectors/wordlist_vectors.g.dart'; +import 'wordkey_support.dart' show fromWtf8; +import 'wordlist_support.dart'; + +final Json vectors = jsonDecode(wordlistVectorsJson) as Json; + +List cases(String name) => (vectors[name]! as List).cast(); + +void main() { + test('the constants and the pinned lists are those of Go', () { + expect(vectors['default_count'], defaultWordCount); + expect(vectors['min_list_size'], minListSize); + expect(vectors['min_words'], minWords); + expect(vectors['min_letters'], minLetters); + // Languages of Go, and the SHA-256 of the file of each of its lists. + final lists = cases('lists'); + expect(wordListLanguages(), [for (final l in lists) l['lang']]); + expect(wordListSha256, {for (final l in lists) l['lang']: l['sha256']}); + }); + + group('checkWordList', () { + test('the cases of TestCheckList of Go', () { + // pal followed by three letters: palaaa, palaab, … + final base = [for (var i = 0; i < minListSize; i++) baseWord(i)]; + checkWordList('es', base); + expect( + outcome(() => checkWordList('xx', base)), + 'no alphabet for the language "xx"', + ); + List withWord(int i, String w) => [...base]..[i] = w; + for (final (list, want) in [ + (base.sublist(0, minListSize - 1), '2047 words, fewer than 2048'), + ( + withWord(5, 'dos palabras'), + 'line 6, "dos palabras", is not one word', + ), + (withWord(5, ' '), 'is not one word'), + (withWord(5, 'mi'), '"mi", is not one word of 3 or more letters'), + (withWord(5, 'casa\u200b'), 'invisible character U+200B'), + // Only the letters of the alphabet of the language, as the list + // writes them: no capitals, no Cyrillic U+0441 that looks like a + // Latin c, no digits, no carriage return of a file with CRLF lines. + ( + withWord(5, 'Palaaf'), + 'line 6, "Palaaf", holds U+0050, which is not in the alphabet of ' + '"es"', + ), + ( + withWord(5, '\u0441asa'), + 'holds U+0441, which is not in the alphabet', + ), + (withWord(5, 'pal1'), 'holds U+0031'), + (withWord(5, 'palaaf\r'), r'line 6, "palaaf\r", holds U+000D'), + ( + withWord(5, base[4]), + 'line 6, "palaae", is the same word as "palaae"', + ), + ( + withWord(5, 'pala\u00e1e'), + 'line 6, "pala\u00e1e", is the same word as "palaae"', + ), + ( + [...withWord(0, 'pap\u00e1'), 'papa'], + '"papa", is the same word as "pap\u00e1"', + ), + ]) { + expect(outcome(() => checkWordList('es', list)), contains(want)); + } + }); + + test('refuses lists as wordkey.CheckList, with its texts', () { + final all = cases('check_list'); + var refused = 0; + var strings = 0; + for (final c in all) { + final name = c['name']! as String; + final lang = c['lang']! as String; + final want = c['result']! as String; + final words = caseWords(c); + expect( + toHex(sha256(joinBytes(words, const [0x0a]))), + c['sha256'], + reason: name, + ); + expect( + outcome(() => checkWordListUtf8(lang, words)), + want, + reason: name, + ); + if (want != 'ok') refused++; + // The same words as Strings, where they have one: the bytes of a + // surrogate are a lone surrogate, as utf8Bytes writes it. + final asStrings = [for (final w in words) fromWtf8(w)]; + if (asStrings.every((s) => s != null)) { + strings++; + expect( + outcome(() => checkWordList(lang, [for (final s in asStrings) s!])), + want, + reason: name, + ); + } + } + expect(all, hasLength(greaterThan(80))); + expect(refused, greaterThan(70)); + // All but three, whose bytes no String has. + expect(strings, all.length - 3); + }); + + test('the alphabet of each code point up to U+017F', () { + final results = cases('alphabet_results'); + expect( + [for (final c in results) c['rune']], + [for (var r = 0; r < 0x180; r++) r], + ); + // The first word is pala, the code point and zz. + final words = caseWords(const {'size': minListSize}); + final accepted = []; + for (final c in results) { + final r = c['rune']! as int; + words[0] = utf8Bytes('pala${String.fromCharCode(r)}zz'); + final got = outcome(() => checkWordListUtf8('es', words)); + expect(got, c['result'], reason: codePointName(r)); + if (got == 'ok') accepted.add(r); + } + // a to z, á, é, í, ñ, ó, ú and ü: all that Go accepts in planes 0, 1 + // and 14. + expect( + String.fromCharCodes(accepted), + 'abcdefghijklmnopqrstuvwxyz' + '\u00e1\u00e9\u00ed\u00f1\u00f3\u00fa\u00fc', + ); + final ok = ((vectors['alphabet']! as Json)['ok']! as List).cast(); + expect([for (final s in ok) s.runes.single], accepted); + }); + }); + + test('parseWordList reads the text of a list as wordkey.List', () { + for (final c in cases('parse')) { + final name = c['name']! as String; + final lang = c['lang']! as String; + final lines = caseWords(c); + final text = concatBytes([ + fromHex(c['prefix']! as String), + joinBytes(lines, fromHex(c['sep']! as String)), + fromHex(c['suffix']! as String), + ]); + expect(toHex(sha256(text)), c['sha256'], reason: name); + final want = c['result']! as String; + expect(outcome(() => parseWordList(lang, text)), want, reason: name); + if (want == 'ok') { + expect(lines, hasLength(c['words']), reason: name); + expect(parseWordList(lang, text), [ + for (final l in lines) decodeUtf8(l), + ], reason: name); + } + } + }); + + test('readWordList refuses a language without a list and other bytes', () { + expect( + outcome(() => readWordList('xx', const [])), + 'wordkey: no word list for "xx"; the lists are es', + ); + final text = utf8Bytes('palaaa\n'); + expect( + outcome(() => readWordList('es', text)), + 'wordkey: the list "es" has the SHA-256 ${toHex(sha256(text))}, not ' + '${wordListSha256['es']}', + ); + // The language first, as Go's List looks for its list first. + expect( + outcome(() => readWordList('ES', text)), + 'wordkey: no word list for "ES"; the lists are es', + ); + }); + + group('generateWords', () { + test('draws the words of wordkey.Generate from the same bytes', () { + final all = cases('generate'); + var drawn = 0; + for (final c in all) { + final name = c['name']! as String; + final size = c['size']! as int; + final n = c['n']! as int; + final read = c['read']! as int; + final error = c['error'] as String?; + final source = CountingSource(streamOf(c['stream']! as Json)); + final list = IndexWords(size); + if (error == null) { + final words = generateWords(list, n, source); + expect( + [for (final w in words) int.parse(w)], + c['indices'], + reason: name, + ); + expect(source.read, read, reason: name); + final next = c['next'] as String?; + if (next != null) { + expect(toHex(randomBytes(source, 4)), next, reason: name); + } + drawn++; + } else if (error.endsWith('EOF')) { + // The bytes end: the source throws, and generateWords lets it + // through, after the draws that Go made in full. + expect( + () => generateWords(list, n, source), + throwsStateError, + reason: name, + ); + expect(source.read, read - read % drawSize(size), reason: name); + } else { + // The arguments, refused before anything is drawn. + expect( + outcome(() => generateWords(list, n, source)), + error, + reason: name, + ); + expect(source.read, 0, reason: name); + } + } + expect(all, hasLength(greaterThan(40))); + expect(drawn, greaterThan(30)); + }); + + test('the cases of TestGenerate of Go', () { + final list = IndexWords(7776); + // The same random bytes draw the same words: generateWords reads + // nothing else. + final a = generateWords(list, 6, seeded('TestGenerate')); + expect(generateWords(list, 6, seeded('TestGenerate')), a); + expect(a.toSet(), hasLength(6)); + // The seed of TestGenerate of Go draws two indices only, 1793 and + // 2081, again and again until it runs out: Go's Generate then fails + // with EOF, and its two results compare equal (see the vectors). + expect( + () => generateWords( + list, + 6, + ReplaySource(repeatBytes(const [7, 1, 200, 33], 64)), + ), + throwsStateError, + ); + for (final (n, want) in [ + (5, 'at least 6 words, not 5'), + (list.length, '7776 words of a list of 7776'), + ]) { + expect( + outcome(() => generateWords(list, n, ReplaySource(const []))), + contains(want), + ); + } + // Without random bytes: the source throws, where Go's Generate fails + // with EOF. + expect( + () => generateWords(list, 6, ReplaySource(const [])), + throwsStateError, + ); + }); + }); + + group('wordBits', () { + double goBits(int size, int count) => hexDouble( + cases( + 'bits', + ).singleWhere((c) => c['size'] == size && c['count'] == count)['hex']! + as String, + ); + + test('the cases of TestBits of Go', () { + // Go: Bits(7776, 1) is math.Log2(7776). + expect(wordBits(7776, 1), goBits(7776, 1)); + expect(wordBits(7776, 1), closeTo(math.log(7776) / math.ln2, 1e-12)); + // 7 words of 7776 are a little under 90.5 bits, and 6 of 2048, the + // fewest that generateWords draws, a little under 66. + for (final (size, count, low, high) in [ + (7776, 0, 0.0, 0.0), + (7776, 7, 90.469, 90.470), + (7776, 8, 103.393, 103.394), + (2048, 6, 65.989, 65.990), + ]) { + expect( + wordBits(size, count), + inInclusiveRange(low, high), + reason: '$size, $count', + ); + } + }); + + test('is Bits of Go, bit for bit', () { + for (final c in cases('bits')) { + final size = c['size']! as int; + final count = c['count']! as int; + final want = c['hex']! as String; + final got = wordBits(size, count); + if (hexDouble(want).isNaN) { + // The NaN of Go, 7ff8000000000001, is not that of Dart. + expect(got.isNaN, isTrue, reason: '$size, $count'); + } else { + expect(doubleHex(got), want, reason: '$size, $count: ${c['bits']}'); + } + } + for (final d in cases('bits_digests')) { + final sizes = (d['sizes']! as List).cast(); + final counts = (d['counts']! as List).cast(); + final digest = Sha256(); + final b = ByteData(8); + for (var size = sizes[0]; size <= sizes[1]; size++) { + for (var count = counts[0]; count <= counts[1]; count++) { + b.setFloat64(0, wordBits(size, count)); + digest.add(Uint8List.sublistView(b)); + } + } + expect(toHex(digest.finish()), d['sha256'], reason: '${d['name']}'); + } + }); + }); +} diff --git a/test/wordlist_vm_test.dart b/test/wordlist_vm_test.dart new file mode 100644 index 0000000..f7fd1b9 --- /dev/null +++ b/test/wordlist_vm_test.dart @@ -0,0 +1,53 @@ +// The word lists against files, and at length: the copy of +// test/vectors/wordlist_vectors.json that wordlist_test.dart reads, a Dart +// constant for the tests compiled to JavaScript, is the JSON file byte for +// byte; and checkWordList gives the result of Go's CheckList for every code +// point of planes 0, 1 and 14. On the VM only: they read a file or take a +// few seconds. +@TestOn('vm') +library; + +import 'dart:convert'; +import 'dart:io'; + +import 'package:datekeys/src/bytes.dart'; +import 'package:datekeys/src/pathrule.dart' show codePointName; +import 'package:datekeys/src/sha256.dart'; +import 'package:datekeys/src/wordlist.dart'; +import 'package:test/test.dart'; + +import 'vectors/wordlist_vectors.g.dart'; +import 'wordlist_support.dart'; + +void main() { + final vectors = jsonDecode(wordlistVectorsJson) as Json; + + test('wordlist_vectors.g.dart holds wordlist_vectors.json', () { + final file = File('test/vectors/wordlist_vectors.json').readAsStringSync(); + expect(wordlistVectorsJson, file); + }); + + test('the alphabet of every code point of planes 0, 1 and 14', () { + // The first word of the base list is pala, the code point and zz: the + // lines of every result, but for the surrogates, have Go's SHA-256. + final a = vectors['alphabet']! as Json; + final words = caseWords(const {'size': minListSize}); + final digest = Sha256(); + final accepted = []; + var count = 0; + for (final p in (a['planes']! as List).cast()) { + for (var r = p << 16; r <= (p << 16 | 0xffff); r++) { + if (r >= 0xd800 && r <= 0xdfff) continue; + final letter = String.fromCharCode(r); + words[0] = utf8Bytes('pala${letter}zz'); + final result = outcome(() => checkWordListUtf8('es', words)); + digest.add(utf8Bytes('${codePointName(r)} $result\n')); + count++; + if (result == 'ok') accepted.add(letter); + } + } + expect(count, a['count']); + expect(toHex(digest.finish()), a['sha256']); + expect(accepted, a['ok']); + }); +} diff --git a/tool/wordlist_go_vectors.go b/tool/wordlist_go_vectors.go new file mode 100644 index 0000000..2707bbb --- /dev/null +++ b/tool/wordlist_go_vectors.go @@ -0,0 +1,727 @@ +//go:build ignore + +// Writes test/vectors/wordlist_vectors.json and the same JSON as a Dart +// constant, wordlist_vectors.g.dart: the results of the word lists of +// package wordkey of the Go reference (generate.go: List, CheckList, +// Generate and Bits, the random words of spec §38.1) for +// lib/src/wordlist.dart. Every expected value is computed here by the Go +// reference; none is written by hand. +// +// - lists: the built-in lists, with the SHA-256, the size and the number +// of words of each file of wordkey/lists, which List reads. +// - parse: the body of List, restated because List reads only its +// built-in lists, on texts of the base list of TestCheckList, "pal" and +// three letters, joined by a separator, with a prefix, a suffix and +// edits: with and without the final LF, CR LF lines, an empty last +// line, a byte order mark, an empty text, bytes that are not valid +// UTF-8. The restatement gives the words of List on every built-in list. +// - check_list: CheckList on the base list of 0 to 17 576 words, edited: +// the cases of TestCheckList; languages without an alphabet; white +// space, controls, invisible and unassigned code points; letters of +// other scripts that look like those of the alphabet, and marks; bytes +// that are not valid UTF-8; words that are one once normalized; and the +// order of the checks within a word and across words. +// - alphabet: CheckList of the base list of 2048 words whose first word +// is "pala", one code point and "zz": the result of every code point up +// to U+017F, and the SHA-256 of the lines "U+XXXX result\n" of every +// code point of planes 0, 1 and 14 but the surrogates. +// - generate: Generate on the Spanish list and on lists of 0 to +// 2^20 + 1 words, while it reads fixed streams instead of crypto/rand: +// the keystream of SeededRandomSource of lib/src/random.dart (ChaCha20 +// under SHA-256(seed), zero nonce); SHA-256 counter blocks; and bytes +// that end, the seed of TestGenerate among them. Each case has the +// indices drawn (and the words, from the Spanish list), the bytes read +// and the next four of an endless stream; or the text of the error and +// the bytes read. +// - bits: Bits of sizes and counts, as the 64 bits of the float64 and its +// shortest decimal; and bits_digests, the SHA-256 of the 8 big-endian +// bytes of each Bits over ranges of sizes and counts, sizes outer. +// +// Binary values are lower-case hexadecimal, and the JSON is ASCII, so that +// the Dart constant is too. The output is the same on every run. It imports +// the package wordkey and reads wordkey/lists, so it runs in an export of +// datekeys-go made with git archive, without changing the repository, at +// 27a75ee, the branch v0.15 after the tag spec-v0.15: +// +// commit=$(git -C ../datekeys-go rev-parse 27a75ee) +// out=$PWD/test/vectors +// tmp=$(mktemp -d) +// git -C ../datekeys-go archive "$commit" | tar -x -C "$tmp" +// cp tool/wordlist_go_vectors.go "$tmp" +// (cd "$tmp" && go run ./wordlist_go_vectors.go -source "$commit" -out "$out") +// rm -rf "$tmp" +package main + +import ( + "bytes" + "crypto/sha256" + "encoding/binary" + "encoding/hex" + "encoding/json" + "flag" + "fmt" + "io" + "log" + "math" + "os" + "path/filepath" + "runtime" + "strconv" + "strings" + + "golang.org/x/crypto/chacha20" + + "g.activething.com/go/DateKeys/wordkey" +) + +func check(err error) { + if err != nil { + log.Fatal(err) + } +} + +func h(s string) string { return hex.EncodeToString([]byte(s)) } + +func hexAll(ss []string) []string { + var out []string + for _, s := range ss { + out = append(out, h(s)) + } + return out +} + +func sum(s string) string { + b := sha256.Sum256([]byte(s)) + return hex.EncodeToString(b[:]) +} + +// result is "ok", or the text of err. +func result(err error) string { + if err != nil { + return err.Error() + } + return "ok" +} + +// --------------------------------------------------------------------------- +// Lists + +// baseWord is word i of the base list of TestCheckList, "pal" and three +// letters: palaaa, palaab, …, up to i = 17 575, palzzz. +func baseWord(i int) string { + return "pal" + string([]rune{'a' + rune(i/676), 'a' + rune(i/26%26), 'a' + rune(i%26)}) +} + +// edit is the word at the index At of a base list replaced by Word, in hex. +type edit struct { + At int `json:"at"` + Word string `json:"word"` +} + +func set(at int, word string) edit { return edit{at, h(word)} } + +// edited is the base list of size words with the edits. +func edited(size int, sets []edit) []string { + l := make([]string, size) + for i := range l { + l[i] = baseWord(i) + } + for _, e := range sets { + b, err := hex.DecodeString(e.Word) + check(err) + l[e.At] = string(b) + } + return l +} + +// listOf is the body of wordkey.List for the text of a list of the caller, +// restated because List reads only its built-in lists. +func listOf(lang, text string) ([]string, error) { + words := strings.Split(strings.TrimSuffix(text, "\n"), "\n") + if err := wordkey.CheckList(lang, words); err != nil { + return nil, fmt.Errorf("wordkey: the list %q: %w", lang, err) + } + return words, nil +} + +type listInfo struct { + Lang string `json:"lang"` + Sha256 string `json:"sha256"` + Bytes int `json:"bytes"` + Words int `json:"words"` +} + +func listInfos() []listInfo { + var out []listInfo + for _, lang := range wordkey.Languages() { + text, err := os.ReadFile(filepath.Join("wordkey", "lists", lang+".txt")) + check(err) + words, err := wordkey.List(lang) + check(err) + again, err := listOf(lang, string(text)) + check(err) + if strings.Join(again, "\n") != strings.Join(words, "\n") { + log.Fatalf("wordkey/lists/%s.txt is not the list of List, or listOf is not its body", lang) + } + out = append(out, listInfo{lang, sum(string(text)), len(text), len(words)}) + } + return out +} + +type parseCase struct { + Name string `json:"name"` + Lang string `json:"lang"` + Size int `json:"size"` + Set []edit `json:"set,omitempty"` + Prefix string `json:"prefix"` + Sep string `json:"sep"` + Suffix string `json:"suffix"` + Sha256 string `json:"sha256"` + Words int `json:"words"` + Result string `json:"result"` +} + +// parseOf reads with listOf the text prefix, the edited base list joined +// by sep, and suffix. +func parseOf(name, lang string, size int, sets []edit, prefix, sep, suffix string) parseCase { + text := prefix + strings.Join(edited(size, sets), sep) + suffix + words, err := listOf(lang, text) + return parseCase{name, lang, size, sets, h(prefix), h(sep), h(suffix), sum(text), len(words), result(err)} +} + +func parseCases() []parseCase { + return []parseCase{ + parseOf("2048 words, one per line, with a final LF", "es", 2048, nil, "", "\n", "\n"), + parseOf("without the final LF", "es", 2048, nil, "", "\n", ""), + parseOf("7776 words", "es", 7776, nil, "", "\n", "\n"), + parseOf("an empty last line: two final LF", "es", 2048, nil, "", "\n", "\n\n"), + parseOf("an empty first line", "es", 2048, nil, "\n", "\n", "\n"), + parseOf("CR LF lines", "es", 2048, nil, "", "\r\n", "\r\n"), + parseOf("CR LF lines, the last without", "es", 2048, nil, "", "\r\n", ""), + parseOf("CR lines", "es", 2048, nil, "", "\r", "\r"), + parseOf("a byte order mark", "es", 2048, nil, "\ufeff", "\n", "\n"), + parseOf("an empty text", "es", 0, nil, "", "\n", ""), + parseOf("an LF only", "es", 0, nil, "", "\n", "\n"), + parseOf("2047 words", "es", 2047, nil, "", "\n", "\n"), + parseOf("the words separated by spaces", "es", 2048, nil, "", " ", "\n"), + parseOf("a language without an alphabet", "xx", 2048, nil, "", "\n", "\n"), + parseOf("a byte that is not valid UTF-8", "es", 2048, []edit{set(6, "pal\xffaa")}, "", "\n", "\n"), + parseOf("a sequence cut at the end of the text", "es", 2048, []edit{set(2047, "palzz\xc3")}, "", "\n", ""), + parseOf("the same word twice", "es", 2048, []edit{set(2000, "palaaa")}, "", "\n", "\n"), + parseOf("a capital letter", "es", 2048, []edit{set(100, "Paldww")}, "", "\n", "\n"), + parseOf("letters of the alphabet", "es", 2048, []edit{set(0, "\u00e1\u00e9\u00ed\u00f3\u00fa\u00fc\u00f1")}, "", "\n", "\n"), + } +} + +type checkCase struct { + Name string `json:"name"` + Lang string `json:"lang"` + Size int `json:"size"` + Set []edit `json:"set,omitempty"` + Append []string `json:"append,omitempty"` + Sha256 string `json:"sha256"` + Result string `json:"result"` +} + +// checkOf runs CheckList on the edited base list of size words followed by +// appends. Sha256 is that of the words joined by LF. +func checkOf(name, lang string, size int, sets []edit, appends ...string) checkCase { + l := append(edited(size, sets), appends...) + return checkCase{name, lang, size, sets, hexAll(appends), sum(strings.Join(l, "\n")), result(wordkey.CheckList(lang, l))} +} + +func checkCases() []checkCase { + at := func(i int, w string) []edit { return []edit{set(i, w)} } + out := []checkCase{ + // TestCheckList, in its order. + checkOf("the base list", "es", 2048, nil), + checkOf("a language without an alphabet", "xx", 2048, nil), + checkOf("2047 words", "es", 2047, nil), + checkOf("two words in a line", "es", 2048, at(5, "dos palabras")), + checkOf("two spaces", "es", 2048, at(5, " ")), + checkOf("two letters", "es", 2048, at(5, "mi")), + checkOf("ZWSP", "es", 2048, at(5, "casa\u200b")), + checkOf("a capital", "es", 2048, at(5, "Palaaf")), + checkOf("a Cyrillic letter that looks like a Latin c", "es", 2048, at(5, "\u0441asa")), + checkOf("a digit", "es", 2048, at(5, "pal1")), + checkOf("the CR of a CR LF line", "es", 2048, at(5, "palaaf\r")), + checkOf("the same word", "es", 2048, at(5, baseWord(4))), + checkOf("the same word once normalized", "es", 2048, at(5, "pala\u00e1e")), + checkOf("papa after pap\u00e1", "es", 2048, at(0, "pap\u00e1"), "papa"), + + // The language and the size. + checkOf("no words", "es", 0, nil), + checkOf("no words in a language without an alphabet", "xx", 0, nil), + checkOf("the empty language", "", 2048, nil), + checkOf("ES, in capitals", "ES", 2048, nil), + checkOf("es and a space", "es ", 2048, nil), + checkOf("espa\u00f1ol", "espa\u00f1ol", 2048, nil), + checkOf("2049 words", "es", 2049, nil), + checkOf("7776 words", "es", 7776, nil), + checkOf("17576 words", "es", 17576, nil), + + // One word of three letters or more, once normalized. + checkOf("an empty word", "es", 2048, at(5, "")), + checkOf("a word of three letters", "es", 2048, at(5, "pal")), + checkOf("\u00f1u, two letters", "es", 2048, at(5, "\u00f1u")), + checkOf("\u00f1u\u00f1, three letters", "es", 2048, at(5, "\u00f1u\u00f1")), + checkOf("a space before", "es", 2048, at(5, " palaaf")), + checkOf("a space after", "es", 2048, at(5, "palaaf ")), + checkOf("a tab inside", "es", 2048, at(5, "pal\taf")), + checkOf("NBSP inside", "es", 2048, at(5, "pal\u00a0af")), + checkOf("NEL inside", "es", 2048, at(5, "pal\u0085af")), + checkOf("the ideographic space inside", "es", 2048, at(5, "pal\u3000af")), + checkOf("LS inside", "es", 2048, at(5, "pal\u2028af")), + checkOf("an LF inside", "es", 2048, at(5, "pal\naf")), + checkOf("two runes and ZWSP: the count before the runes", "es", 2048, at(5, "p\u200b")), + checkOf("three letters with a mark that goes: two", "es", 2048, at(5, "pa\u0301")), + checkOf("a\u0301b, two letters once normalized", "es", 2048, at(5, "a\u0301b")), + + // The runes of the normalized word. + checkOf("a control", "es", 2048, at(5, "pal\x01af")), + checkOf("DEL", "es", 2048, at(5, "pal\x7faf")), + checkOf("a C1 control", "es", 2048, at(5, "pal\u0080af")), + checkOf("a control and a capital: the runes before the alphabet", "es", 2048, at(5, "Pal\x01af")), + checkOf("a soft hyphen", "es", 2048, at(5, "pa\u00ad")), + checkOf("ZWJ", "es", 2048, at(5, "pal\u200daf")), + checkOf("a byte order mark", "es", 2048, at(5, "\ufeffpalaaf")), + checkOf("an unassigned code point", "es", 2048, at(5, "pal\u0378")), + checkOf("a noncharacter", "es", 2048, at(5, "pal\ufffe")), + checkOf("a tag", "es", 2048, at(5, "pal\U000e0041af")), + + // The alphabet, on the word as the list writes it. + checkOf("the letters of the alphabet", "es", 2048, at(5, "abcdefghijklmnopqrstuvwxyz\u00e1\u00e9\u00ed\u00f3\u00fa\u00fc\u00f1")), + checkOf("an acute accent in NFD", "es", 2048, at(5, "pala\u0301e")), + checkOf("a diaeresis in NFD", "es", 2048, at(5, "palaa\u0308")), + checkOf("a tilde in NFD", "es", 2048, at(5, "pan\u0303o")), + checkOf("\u00c1, a capital with an accent", "es", 2048, at(5, "\u00c1baco")), + checkOf("\u00d1, a capital", "es", 2048, at(5, "\u00d1and\u00fa")), + checkOf("a grave accent", "es", 2048, at(5, "pal\u00e0a")), + checkOf("a circumflex", "es", 2048, at(5, "pal\u00e2a")), + checkOf("\u00e4", "es", 2048, at(5, "pal\u00e4a")), + checkOf("\u00e7", "es", 2048, at(5, "pal\u00e7a")), + checkOf("\u00f6", "es", 2048, at(5, "pal\u00f6a")), + checkOf("\u00fd", "es", 2048, at(5, "pal\u00fda")), + checkOf("\u00df", "es", 2048, at(5, "pal\u00dfa")), + checkOf("a Cyrillic a", "es", 2048, at(5, "pal\u0430a")), + checkOf("a Greek omicron", "es", 2048, at(5, "pal\u03bfa")), + checkOf("a full-width a", "es", 2048, at(5, "pal\uff41a")), + checkOf("a mathematical bold a", "es", 2048, at(5, "pal\U0001d41aa")), + checkOf("the Kelvin sign", "es", 2048, at(5, "pal\u212aa")), + checkOf("a dotless i", "es", 2048, at(5, "pal\u0131a")), + checkOf("a hyphen", "es", 2048, at(5, "pal-af")), + checkOf("an apostrophe", "es", 2048, at(5, "pal'af")), + checkOf("a backtick and a brace, around a to z", "es", 2048, at(5, "pal`{")), + checkOf("an emoji", "es", 2048, at(5, "pal\U0001f600")), + + // Bytes that are not valid UTF-8: U+FFFD, which no alphabet holds. + checkOf("a byte that is not valid UTF-8", "es", 2048, at(5, "pal\xffaa")), + checkOf("a surrogate in UTF-8 bytes", "es", 2048, at(5, "\xed\xa0\x80aaa")), + checkOf("a sequence cut short", "es", 2048, at(5, "pala\xc3")), + checkOf("an overlong NUL", "es", 2048, at(5, "\xc0\x80aaa")), + checkOf("U+FFFD itself", "es", 2048, at(5, "pal\ufffdaa")), + + // The same word once normalized, and the order across words. + checkOf("a\u00f1o and ano", "es", 2048, []edit{set(5, "a\u00f1o"), set(6, "ano")}), + checkOf("ping\u00fcino and pinguino", "es", 2048, []edit{set(5, "pinguino"), set(9, "ping\u00fcino")}), + checkOf("the same word, the first of the list last", "es", 2048, nil, "palaaa"), + checkOf("a capital of a word of the list: the alphabet before the same word", "es", 2048, at(5, "PALAAE")), + checkOf("an error at line 4 and another at line 6", "es", 2048, []edit{set(3, "Mal"), set(5, "pa")}), + checkOf("an error at the last line", "es", 2048, at(2047, "x")), + checkOf("an empty last line", "es", 2048, nil, ""), + } + return out +} + +// --------------------------------------------------------------------------- +// The alphabet of every code point + +type runeResult struct { + Rune int `json:"rune"` + Result string `json:"result"` +} + +type alphabetHead struct { + Word string `json:"word"` + Planes []int `json:"planes"` + Count int `json:"count"` + Sha256 string `json:"sha256"` + Ok []string `json:"ok"` +} + +func alphabet() (alphabetHead, []runeResult) { + planes := []int{0, 1, 14} + l := edited(2048, nil) + digest := sha256.New() + var results []runeResult + var ok []string + count := 0 + for _, p := range planes { + for r := rune(p << 16); r <= rune(p<<16|0xffff); r++ { + if r >= 0xd800 && r <= 0xdfff { + continue + } + l[0] = "pala" + string(r) + "zz" + res := result(wordkey.CheckList("es", l)) + fmt.Fprintf(digest, "U+%04X %s\n", r, res) + count++ + if r <= 0x17f { + results = append(results, runeResult{int(r), res}) + } + if res == "ok" { + ok = append(ok, string(r)) + } + } + } + head := alphabetHead{"pala, the code point and zz, the first word of the base list of 2048", planes, count, hex.EncodeToString(digest.Sum(nil)), ok} + return head, results +} + +// --------------------------------------------------------------------------- +// Generate + +// seeded is the keystream of SeededRandomSource of lib/src/random.dart: +// ChaCha20 under SHA-256(seed), with a zero nonce, from block 0. +type seeded struct{ c *chacha20.Cipher } + +func newSeeded(seed string) *seeded { + key := sha256.Sum256([]byte(seed)) + c, err := chacha20.NewUnauthenticatedCipher(key[:], make([]byte, chacha20.NonceSize)) + check(err) + return &seeded{c} +} + +func (s *seeded) Read(p []byte) (int, error) { + clear(p) + s.c.XORKeyStream(p, p) + return len(p), nil +} + +// counter is SHA-256(label ‖ i) for i = 0, 1, …, a 32-bit big-endian +// counter, one block after the other. +type counter struct { + label []byte + i uint32 + block []byte +} + +func (c *counter) Read(p []byte) (int, error) { + for n := 0; n < len(p); { + if len(c.block) == 0 { + b := sha256.Sum256(binary.BigEndian.AppendUint32(bytes.Clone(c.label), c.i)) + c.block = b[:] + c.i++ + } + k := copy(p[n:], c.block) + c.block = c.block[k:] + n += k + } + return len(p), nil +} + +// counting counts the bytes read from r. +type counting struct { + r io.Reader + n int +} + +func (c *counting) Read(p []byte) (int, error) { + n, err := c.r.Read(p) + c.n += n + return n, err +} + +// stream is what a case of generate reads instead of crypto/rand: kind +// seeded, the keystream of Seed; counter, the blocks of the label Seed; or +// bytes, Hex repeated Repeat times, which end. +type stream struct { + Kind string `json:"kind"` + Seed string `json:"seed,omitempty"` + Hex string `json:"hex,omitempty"` + Repeat int `json:"repeat,omitempty"` +} + +func (s stream) reader() io.Reader { + switch s.Kind { + case "seeded": + return newSeeded(s.Seed) + case "counter": + return &counter{label: []byte(s.Seed)} + case "bytes": + b, err := hex.DecodeString(s.Hex) + check(err) + return bytes.NewReader(bytes.Repeat(b, s.Repeat)) + } + log.Fatalf("stream kind %q", s.Kind) + return nil +} + +func seed(s string) stream { return stream{Kind: "seeded", Seed: s} } + +func given(hexBytes string, repeat int) stream { + return stream{Kind: "bytes", Hex: hexBytes, Repeat: repeat} +} + +type generateCase struct { + Name string `json:"name"` + List string `json:"list,omitempty"` + Size int `json:"size"` + N int `json:"n"` + Stream stream `json:"stream"` + Indices []int `json:"indices,omitempty"` + Words []string `json:"words,omitempty"` + Read int `json:"read"` + Next string `json:"next,omitempty"` + Error string `json:"error,omitempty"` +} + +// numbers is a list of size words, "0", "1", …: Generate reads only its +// length and the words it draws, whose indices they are. +func numbers(size int) []string { + l := make([]string, size) + for i := range l { + l[i] = strconv.Itoa(i) + } + return l +} + +func generateOf(name, listName string, list []string, n int, s stream) generateCase { + r := &counting{r: s.reader()} + words, err := wordkey.Generate(list, n, r) + c := generateCase{Name: name, List: listName, Size: len(list), N: n, Stream: s, Read: r.n} + if err != nil { + c.Error = err.Error() + return c + } + index := make(map[string]int, len(list)) + for i, w := range list { + index[w] = i + } + for _, w := range words { + c.Indices = append(c.Indices, index[w]) + } + if listName != "" && n <= 24 { + c.Words = words + } + if s.Kind != "bytes" { + next := make([]byte, 4) + _, err := io.ReadFull(r.r, next) + check(err) + c.Next = hex.EncodeToString(next) + } + return c +} + +func generateCases() []generateCase { + es, err := wordkey.List("es") + check(err) + var out []generateCase + add := func(c generateCase) { out = append(out, c) } + // The Spanish list, from the keystream of a seed and from SHA-256 + // counter blocks. + for _, n := range []int{6, wordkey.DefaultCount, 8, 12, 24} { + add(generateOf(fmt.Sprintf("%d words of the Spanish list", n), "es", es, n, seed(fmt.Sprintf("wordkey.Generate es %d", n)))) + } + for _, n := range []int{6, wordkey.DefaultCount, 12} { + add(generateOf(fmt.Sprintf("%d words of the Spanish list, SHA-256 counter blocks", n), "es", es, n, stream{Kind: "counter", Seed: fmt.Sprintf("wordkey.Generate counter %d", n)})) + } + add(generateOf("3888 words of the Spanish list, the most", "es", es, len(es)/2, seed("wordkey.Generate es 3888"))) + // Lists of every number of bytes of a draw of crypto/rand.Int, with and + // without draws again. + for _, size := range []int{12, 13, 16, 17, 100, 255, 256, 257, 2047, 2048, 2049, 4096, 7775, 7776, 7777, 8192, 65535, 65536, 65537, 100000, 1<<20 + 1} { + add(generateOf(fmt.Sprintf("6 words of %d", size), "", numbers(size), 6, seed(fmt.Sprintf("wordkey.Generate %d", size)))) + } + add(generateOf("12 words of 65537, SHA-256 counter blocks", "", numbers(65537), 12, stream{Kind: "counter", Seed: "wordkey.Generate counter 65537"})) + // The most words of small lists: indices drawn twice, again and again. + for _, size := range []int{12, 13, 17, 100} { + add(generateOf(fmt.Sprintf("%d words of %d, the most", size/2, size), "", numbers(size), size/2, seed(fmt.Sprintf("wordkey.Generate %d most", size)))) + } + // Bytes that end. + add(generateOf("the seed of TestGenerate: two indices only, then EOF", "es", es, 6, given("0701c821", 64))) + add(generateOf("twelve bytes, six indices", "es", es, 6, given("000000010002000300040005", 1))) + add(generateOf("8191 and 8032 drawn again, 0 drawn twice, 7775 the last index", "es", es, 6, given("1fff00001f601e5f00000001000200030004", 1))) + add(generateOf("the three bits above the 13 of 7775 are cleared", "es", es, 6, given("e000ffff21002200230024002500", 1))) + add(generateOf("the bytes end inside a draw", "es", es, 6, given("0000000100", 1))) + add(generateOf("no bytes", "es", es, 6, given("", 0))) + // The arguments, refused before anything is read. + for _, n := range []int{5, 0, -1, len(es)/2 + 1, len(es)} { + add(generateOf(fmt.Sprintf("%d words of the Spanish list", n), "es", es, n, seed("never read"))) + } + for _, c := range []struct{ size, n int }{{11, 6}, {0, 6}, {0, 5}, {12, 7}, {13, 7}} { + add(generateOf(fmt.Sprintf("%d words of %d", c.n, c.size), "", numbers(c.size), c.n, seed("never read"))) + } + return out +} + +// --------------------------------------------------------------------------- +// Bits + +type bitsCase struct { + Size int `json:"size"` + Count int `json:"count"` + Bits string `json:"bits"` + Hex string `json:"hex"` +} + +func bitsOf(size, count int) bitsCase { + b := wordkey.Bits(size, count) + return bitsCase{size, count, strconv.FormatFloat(b, 'g', -1, 64), fmt.Sprintf("%016x", math.Float64bits(b))} +} + +func bitsCases() []bitsCase { + var out []bitsCase + for _, size := range []int{1, 2, 3, 5, 12, 13, 100, 255, 256, 257, 2047, 2048, 2049, 4096, 7775, 7776, 7777, 8192, 10000, 65535, 65536, 65537, 1 << 20, 1<<31 - 1, 1 << 31, 1<<32 - 1, 1 << 32, 1<<32 + 1, 1<<52 + 1, 1<<53 - 1, 1 << 53} { + for _, count := range []int{0, 1, 2, 6, 7, 8, 12} { + out = append(out, bitsOf(size, count)) + } + } + // Go adds log2 of 0, −Inf, and of a negative number, NaN, and adds + // nothing for a negative count. + for _, c := range [][2]int{{0, 1}, {-1, 1}, {7776, -1}, {0, 0}} { + out = append(out, bitsOf(c[0], c[1])) + } + return out +} + +type bitsDigest struct { + Name string `json:"name"` + Sizes [2]int `json:"sizes"` + Counts [2]int `json:"counts"` + Sha256 string `json:"sha256"` +} + +func digestOf(name string, sizes, counts [2]int) bitsDigest { + d := sha256.New() + var b [8]byte + for size := sizes[0]; size <= sizes[1]; size++ { + for count := counts[0]; count <= counts[1]; count++ { + binary.BigEndian.PutUint64(b[:], math.Float64bits(wordkey.Bits(size, count))) + d.Write(b[:]) + } + } + return bitsDigest{name, sizes, counts, hex.EncodeToString(d.Sum(nil))} +} + +func bitsDigests() []bitsDigest { + return []bitsDigest{ + digestOf("one word of 1 to 65536: the log2 of Go", [2]int{1, 65536}, [2]int{1, 1}), + digestOf("6 to 8 words of 2048 to 10000", [2]int{2048, 10000}, [2]int{6, 8}), + digestOf("0 to 600 words of 7776", [2]int{7776, 7776}, [2]int{0, 600}), + digestOf("1 word of 2^32 - 4096 to 2^32 + 4096", [2]int{1<<32 - 4096, 1<<32 + 4096}, [2]int{1, 1}), + } +} + +// --------------------------------------------------------------------------- +// JSON + +// ascii escapes every code point above U+007F of JSON as \uXXXX, in UTF-16 +// for those above U+FFFF: the same JSON, in ASCII. +func ascii(b []byte) []byte { + var out bytes.Buffer + for _, r := range string(b) { + switch { + case r < 0x80: + out.WriteByte(byte(r)) + case r < 0x10000: + fmt.Fprintf(&out, `\u%04x`, r) + default: + r -= 0x10000 + fmt.Fprintf(&out, `\u%04x\u%04x`, 0xd800+(r>>10), 0xdc00+(r&0x3ff)) + } + } + return out.Bytes() +} + +func marshal(v any) []byte { + var b bytes.Buffer + enc := json.NewEncoder(&b) + enc.SetEscapeHTML(false) + check(enc.Encode(v)) + return ascii(bytes.TrimSuffix(b.Bytes(), []byte("\n"))) +} + +// list writes the items of a JSON array one per line. +func list[T any](w *bytes.Buffer, key string, items []T, last bool) { + fmt.Fprintf(w, " %q: [\n", key) + for i, it := range items { + w.WriteString(" ") + w.Write(marshal(it)) + if i < len(items)-1 { + w.WriteByte(',') + } + w.WriteByte('\n') + } + w.WriteString(" ]") + if !last { + w.WriteByte(',') + } + w.WriteByte('\n') +} + +func main() { + outDir := flag.String("out", "", "the directory test/vectors of datekeys-dart") + source := flag.String("source", "", "the commit of datekeys-go") + flag.Parse() + if *outDir == "" || *source == "" { + log.Fatal("usage: go run wordlist_go_vectors.go -source COMMIT -out DIR") + } + lists := listInfos() + parse := parseCases() + checks := checkCases() + alpha, runes := alphabet() + gen := generateCases() + bits := bitsCases() + digests := bitsDigests() + + var w bytes.Buffer + w.WriteString("{\n") + head := []struct { + key string + v any + }{ + {"description", "The word lists of package wordkey of the Go reference (generate.go, spec \u00a738.1) for lib/src/wordlist.dart; see tool/wordlist_go_vectors.go. " + + "Binary values and words are lower-case hex. The base list is word i = pal and three letters, a + i/676, a + i/26%26 and a + i%26; a case of size n takes its first n words, replaces the word at each at of set, and adds those of append. " + + "lists: the SHA-256, bytes and words of each built-in list. parse: the body of List on the text prefix, the base list joined by sep, and suffix (sha256 is that of the text): the words read, and ok or the error. " + + "check_list: CheckList, ok or the error (sha256 is that of the words joined by LF). alphabet: CheckList of the base list of 2048 whose first word is pala, a code point and zz, for each code point of the planes but the surrogates: the SHA-256 of the lines U+XXXX result, the code points of the words it accepts, and alphabet_results, each result up to U+017F. " + + "generate: Generate on the list of the Spanish words (list es) or on a list of size words whose indices they are, reading a stream: seeded, the keystream of SeededRandomSource of the seed; counter, SHA-256 of the label and a 32-bit big-endian counter from 0, block after block; bytes, hex repeated repeat times, which end. The indices drawn, the bytes read and the next four of an endless stream, or the error. " + + "bits: Bits, its shortest decimal and the hex of its float64. bits_digests: the SHA-256 of the 8 big-endian bytes of each Bits of the sizes and counts, inclusive, sizes outer."}, + {"generator", "tool/wordlist_go_vectors.go, " + runtime.Version()}, + {"source", *source}, + {"default_count", wordkey.DefaultCount}, + {"min_list_size", wordkey.MinListSize}, + {"min_words", wordkey.MinWords}, + {"min_letters", wordkey.MinLetters}, + {"alphabet", alpha}, + } + for _, kv := range head { + fmt.Fprintf(&w, " %q: %s,\n", kv.key, marshal(kv.v)) + } + list(&w, "lists", lists, false) + list(&w, "parse", parse, false) + list(&w, "check_list", checks, false) + list(&w, "alphabet_results", runes, false) + list(&w, "generate", gen, false) + list(&w, "bits", bits, false) + list(&w, "bits_digests", digests, true) + w.WriteString("}\n") + + var parsed any + if err := json.Unmarshal(w.Bytes(), &parsed); err != nil { + log.Fatalf("the JSON does not parse: %v", err) + } + if bytes.Contains(w.Bytes(), []byte("'''")) { + log.Fatal("the JSON holds three quotes") + } + path := filepath.Join(*outDir, "wordlist_vectors.json") + check(os.WriteFile(path, w.Bytes(), 0o644)) + fmt.Printf("wrote %s, %d bytes: %d lists, %d texts, %d lists checked, %d code points, %d draws, %d bits, %d digests\n", + path, w.Len(), len(lists), len(parse), len(checks), alpha.Count, len(gen), len(bits), len(digests)) + dart := "// Generated by tool/wordlist_go_vectors.go from wordlist_vectors.json, for\n" + + "// the tests that also run compiled to JavaScript, where no file can be\n" + + "// read. Do not edit.\n\n" + + "/// The text of test/vectors/wordlist_vectors.json.\n" + + "const wordlistVectorsJson = r'''\n" + w.String() + "''';\n" + dpath := filepath.Join(*outDir, "wordlist_vectors.g.dart") + check(os.WriteFile(dpath, []byte(dart), 0o644)) + fmt.Printf("wrote %s\n", dpath) +}