package emozi import ( base14 "github.com/fumiama/go-base16384" ) type 声母枚举 uint8 // String 国际音标 func (sm 声母枚举) String() string { a := sm * 3 b := a + [...]声母枚举{1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 2, 3, 1, 2, 3, 1, 1, 2, 3, 1, 1, 1, 1, 1}[sm] s := []rune("p pʰ m f t tʰ n l k kʰ x tɕ tɕʰɕ ʈʂ ʈʂʰʂ ɻ ts tsʰs j w ɥ 0 ")[a:b] return string(s) } const ( 声母b 声母枚举 = iota 声母p 声母m 声母f 声母d 声母t 声母n 声母l 声母g 声母k 声母h 声母j 声母q 声母x 声母zh 声母ch 声母sh 声母r 声母z 声母c 声母s 声母yi 声母w 声母yu 声母0 ) // 声母 可以有多个颜文字与之对应 但有时系统可能无法显示 var 声母 = [...][]string{ // b: 鼻笔八 {"👃", "🖊️", "🎱"}, // p: 跑跑跑票票牌牌 {"🏃", "🏃‍♀️", "🏃‍♂️", "🎫", "🎟️", "🃏", "🎴"}, // m: 马马猫猫猫猫锚面面门麦米木蜜帽帽帽麦 {"🐴", "🐎", "🐱", "🐈", "🐈‍⬛", "😺", "⚓️", "🍜", "🍝", "🚪", "🌾", "🍚", "🪵", "🍯", "🎩", "👒", "🧢", "🎙️"}, // f: 斧肺 {"🪓", "🫁"}, // d: 刀豆蛋灯灯洞 {"🔪", "🫘", "🥚", "💡", "🪔", "🕳️"}, // t: 腿糖兔兔桶桃 {"🦵", "🍬", "🐰", "🐇", "🪣", "🍑"}, // n: 奶鸟牛 {"🥛", "🐦", "🐮"}, // l: 鹿鹿冷龙龙莲 {"🦌", "🫎", "🥶", "🐲", "🐉", "🪷"}, // g: 瓜鼓龟狗勾跪跪跪 {"🍉", "🥁", "🐢", "🐶", "🪝", "🧎", "🧎‍♀️", "🧎‍♂️"}, // k: 哭裤 {"😭", "👖"}, // h: 花花花花花花花花火虎虎猴猴 {"🌹", "🌼", "💐", "🌷", "🌸", "🌺", "🥀", "🪻", "🔥", "🐯", "🐅", "🐒", "🐵"}, // j: 加减酒酒鸡鸡剑姜镜脚 {"➕", "➖", "🍷", "🍺", "🐔", "🐓", "🗡️", "🫚", "🪞", "🦶"}, // q: 茄钱钱钱钱钱棋 {"🍆", "💰", "💴", "💵", "💶", "💸", "♟️"}, // x: 下下虾虾虾雪星星星星熊象蟹 {"👇", "⬇️", "🦐", "🍤", "🦞", "❄️", "🌟", "✨", "⭐️", "💫", "🐻", "🐘", "🦀️"}, // zh: 猪猪针针 {"🐽", "🐷", "🪡", "💉"}, // ch: 茶茶车车车车床床除虫 {"🍵", "☕️", "🚗", "🚘", "🚙", "🛻", "🛏️", "🛌", "➗", "🐛"}, // sh: 水水书书书书书书上上上石山山山树树树蛇鼠鼠鼠珊18 {"💦", "💧", "📖", "📕", "📗", "📘", "📙", "📚", "⬆️", "☝️", "👆", "🪨", "⛰️", "🏔️", "🗻", "🌲", "🌳", "🌴", "🐍", "🐭", "🐀", "🐁", "🪸", "🔞"}, // r: 肉日日日 {"🥩", "🌞", "☀️", "🌅"}, // z: 左左左 c: 错错错错 s: 锁伞伞伞伞蒜 {"👈", "⬅️", "⬅"}, {"❌", "🙅", "🙅‍♀️", "🙅‍♂️"}, {"🔒", "🌂", "☔️", "⛱️", "☂️", "🧄"}, // yi: 羊羊牙药盐 w: 袜雾网碗 yu: 雨鱼鱼 0: 两种椅子 {"🐑", "🐐", "🦷", "💊", "🧂"}, {"🧦", "🌫️", "🕸️", "🥣"}, {"🐟", "🌧️", "🐠"}, {"🪑", "💺"}, } func 低阶逆初始化(表 [][]string, 倍数 int) map[rune][]string { m := make(map[rune][]string, len(表)*倍数) for _, lst := range 表 { for _, s := range lst { k := []rune(s)[0] m[k] = append(m[k], s) } } return m } // 低阶逆声母 rune声母到声母的逆映射 var 低阶逆声母 = 低阶逆初始化(声母[:], 32) func 逆初始化[T ~uint8](表 [][]string, 倍数 int) map[string]T { m := make(map[string]T, len(表)*倍数) for i, lst := range 表 { for _, s := range lst { m[s] = T(i) } } return m } // 逆声母 声母到枚举的逆映射 var 逆声母 = 逆初始化[声母枚举](声母[:], 32) type 韵母枚举 uint8 // String 国际音标 func (ym 韵母枚举) String() string { return [...]string{ "ä", "ɔ", "ɤ", "i", "ɿ", "u", "y", "ɐɚ̯", "aɪ̯", "u̯aɪ̯", "eɪ̯", "u̯eɪ̯", "ɑʊ̯", "i̯ɑʊ̯", "oʊ̯", "i̯oʊ̯", "i̯ä", "u̯ä", "u̯o", "i̯ɛ", "y̯ɛ", "an", "i̯ɛn", "u̯an", "y̯ɛn", "ən", "u̯ən", "in", "yn", "ɑŋ", "i̯ɑŋ", "u̯ɑŋ", "ɤŋ", "iŋ", "u̯əŋ", "ʊŋ", "i̯ʊŋ", }[ym] } const ( 韵母a 韵母枚举 = iota 韵母o 韵母e 韵母yi 韵母ri 韵母wu 韵母yu 韵母er 韵母ai 韵母uai 韵母ei 韵母ui 韵母ao 韵母iao 韵母ou 韵母iu 韵母ia 韵母ua 韵母uo 韵母ie 韵母yue 韵母an 韵母ian 韵母uan 韵母yuan 韵母en 韵母un 韵母in 韵母yun 韵母ang 韵母iang 韵母uang 韵母eng 韵母ing 韵母ueng 韵母ong 韵母iong ) // 韵母 仅由一种意象表示 var 韵母 = [...][]string{ {"😧", "🤔️"}, {"😲"}, {"😋"}, {"👔", "👗", "👕", "👚"}, {"🌞", "☀️", "🌅"}, {"🈚", "🌫️"}, {"🐟", "🌧️"}, {"👂"}, {"💟", "❤️", "💗", "💓", "🫶", "💕", "💖", "💘", "💙", "💚", "💛", "💜", "💝", "💞", "🧡"}, {"🥢"}, {"😩"}, {"🐢"}, {"🐱", "🐈", "🐈‍⬛", "😺"}, {"💊"}, {"🤮", "🤢"}, {"👉", "➡️"}, {"🦷"}, {"🧦"}, {"🌀"}, {"👴", "✌️"}, {"🌙", "🌕", "🌛", "🌝"}, {"🔐"}, {"🚬"}, {"🥣", "🍚"}, {"🔘", "⭕️"}, {"😐"}, {"😘", "💋"}, {"🎵"}, {"☁"}, {"👍"}, {"🐑"}, {"🥅", "🕸️"}, {"💡", "🪔"}, {"🦅"}, {"🐝"}, {"🌈"}, {"😳"}, // jiong 囧 } // 低阶逆韵母 rune韵母到韵母的逆映射 var 低阶逆韵母 = 低阶逆初始化(韵母[:], 8) // 逆韵母 韵母到枚举的逆映射 var 逆韵母 = 逆初始化[韵母枚举](韵母[:], 8) type 声调枚举 uint8 // String 返回传统调名 func (t 声调枚举) String() string { return [...]string{ "阴平", "阳平", "上声", "去声", "轻声", }[t] } const ( 阴平 声调枚举 = iota 阳平 上声 去声 轻声 ) var 声调 = [...][]string{{"🍉"}, {"🧗", "🧗‍♀️", "🧗‍♂️", "🦎"}, {"🐴", "🐎"}, {"😨"}, {"😯"}} // 低阶逆声调 rune声调到声调的逆映射 var 低阶逆声调 = 低阶逆初始化(声调[:], 4) // 逆声调 声调到枚举的逆映射 var 逆声调 = 逆初始化[声调枚举](声调[:], 4) // 校验表 用 校验表长度 个unicode控制字符做校验和验证此序列是由本程序生成而非手写的 // // 具体做法是先对后面的文本做crc32然后取 校验表长度^校验字节数 的模 var 校验表 = func() []rune { x, err := base14.UTF16BE2UTF8(base14.StringToBytes("\x20\x0b\x20\x0c\x20\x0d\x20\x0e\x20\x2a\x20\x2c\x20\x2d\x20\x60\x20\x61\x20\x62\x20\x63\x20\x64\x20\x65\x20\x66\x20\x68\x20\x69\x20\x6a\x20\x6b\x20\x6c\x20\x6d\x20\x6e\x20\x6f")) if err != nil { panic(err) } return []rune(base14.BytesToString(x)) }() // 校验表长度 22 var 校验表长度 = len(校验表) // 校验字节数 默认为 3, 不得大于 3 const 校验字节数 = 3 // 校验模 校验表长度^校验字节数 var 校验模 = uint32(0) // 校验倍数 校验表长度乘方表 var 校验倍数 = func() []uint32 { tab := make([]uint32, 校验字节数) tab[0] = 1 for i := 1; i < 校验字节数; i++ { tab[i] = tab[i-1] * uint32(校验表长度) } 校验模 = tab[校验字节数-1] * uint32(校验表长度) return tab }() // 逆校验表 还原校验和用 var 逆校验表 = func() map[rune]uint8 { m := make(map[rune]uint8, 64) for i, c := range 校验表 { m[c] = uint8(i) } return m }() // 逆部首后备 部首后备逆查表 一对多 var 逆部首后备 = func() map[string][]rune { m := make(map[string][]rune, len(部首后备)*4) for r, e := range 部首后备 { if 无此字符(m[e], r) { m[e] = append(m[e], r) } } return m }()