阅读:6607回复:6
字、碼互相轉譯功能
【簡介】
之前有人提過這篇 ,裡面有提過的這裡就不再贅言,其中的11樓稍提了一下有提供這功能的輸入法與適用條件 以自己用的中文輸入法拆碼方式為例,簡單舉個例子: 「小小輸入法」幾個字轉譯為字碼:「sa sa cai bp wu 」 「sa sa cai bp wu 」則可轉譯成文字:「小小輸入法」 ※以下所提的內容,均以自己用的輸入法拆碼方式為例做說明 這功能較適合於選字率低的輸入法,否則選字率過高,轉譯出來結果可能很奇怪,也沒什意義可言 也許有人覺得這功能只是噱頭,無實際用途,不過當初做出這功能的輸入法是有他的考量 因該輸入法不是系統內建,為方便使用者萬一在沒有該輸入法的環境時,可以暫時先將想輸入的東西,以英文代碼存下 等到回到有該輸入法的環境後,即可用此功能轉成中文 其主要目的並不是當加密文,讓人家看不懂用的,加密的軟體已太多,不須再用這個來插一腳。何況這也不是很好的加密方式,很容易解密 自己過去倒是有幾個時機使用此功能,現在使用的時機很少了,因用小小這平台可四處帶著走 這類時機像剛好沒有可用的輸入法,網路連線也不方便,無法用線上版的輸入法。只好暫時先用英文代碼,之後再轉譯成中文;或要寄中文訊息給朋友,卻無法輸入中文,而朋友也使用相同輸入法,懂得如何轉譯成中文 以下利用小小的「命令直達車」功能,模擬此「字、碼互相轉譯功能」 這個做法的條件、限制,及使用環境大致與這篇 所提相同的 這裡再補充三點限制,也就是這裡所用碼表的條件: 第一是拆碼方式的選字率要低,結果才會理想;否則結果可能讓你無法接受,而不想用此功能 第二是目前僅適用於一行中只含一組字碼對應一文字的碼表 也就是要像這種的 a 對 aa 寸 aaa 鑫 aaa 龘 aaa 鑆 aaar 鑆 ... 不能像這種的 a 對 aa 寸 aaa 鑫 龘 鑆 aaar 鑆 ... 第二項限制是因為目前自己做的程式只處理像第一種的格式 (為方便說明,上述碼表片段範例中,將空白前面的英文代碼稱為「字碼」,簡稱為「碼」;空白後的中文字或符號稱為「字符」,簡稱為「字」) 字符最好是單一字元的文字或符號 第三是碼表中要出現[data]這個分隔指示。最好是乾淨格式的碼表,以免引發錯誤 碼表最好已按照字的使用頻率排列過,即常用字排在前,效果會較好 自己的碼表是用utf-8編碼,若用GBK編碼,主程式要調整 【設置方法】 以上交代過基本的需知,再來說明設置方法 一、在分詞庫中加入命令直通車的指令 xmode $GO(碼字轉譯,tw\plugin\xmode.pyw) ymode $GO(字碼轉譯,tw\plugin\ymode.pyw) 二、做好xmode.pyw與ymode.pyw 取名為xmode與ymode是源自原始設計此功能的輸入法用來啟用解譯功能的按鍵方式,且官方說明文件沒公開此功能,所以自己就私底下將其稱為X模式,反向的解譯則稱為Y模式 利用二支python小程式執行下述的主程式,將自己的檔案名稱傳入,當成是執行參數 二支程式的內容完全一樣,只有檔案名稱不一樣 #!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import sys def main(): path, filename = os.path.split(sys.argv[0]) basename, ext = os.path.splitext(filename) os.chdir('tw/plugin/') os.system('translate.pyw ' + basename) if __name__ == '__main__': main() 三、主程式:translate.pyw #!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys ##import os import win32clipboard import win32con import win32gui code_table = '../wushiamy.txt' def copy_from_clipboard(): '''從剪貼簿複製文字,但排除沒有實質內容者''' win32clipboard.OpenClipboard() t = win32clipboard.GetClipboardData(win32con.CF_UNICODETEXT) win32clipboard.CloseClipboard() if t.strip('\n ') != '': return t def copy_to_clipboard(text): '''文字複製到剪貼簿''' win32clipboard.OpenClipboard() win32clipboard.EmptyClipboard() win32clipboard.SetClipboardData(win32con.CF_UNICODETEXT, text) win32clipboard.CloseClipboard() def prepare_dict(code_table): '''準備兩個轉譯用的字典,其中一個屬僅中介的暫時性字典 及組字鍵之字元串列''' global dict_code, dict_cword, keys_lst with open(code_table, encoding='utf-8') as f: start = False for line in f: line = line.strip('\n').lower() if not start: if line.startswith('[data]'): start = True elif line.startswith('key='): s, keys = line.split('=') else: continue else: if line.startswith('#') or line == '': continue code, cword = line.split(' ', 1) if not dict_cword.get(cword): dict_cword[cword] = {} if not dict_code.get(code): dict_code[code] = cword dict_cword[cword][code] = False else: dict_cword[cword][code] = True #表示要選字的碼 keys_lst = [c for c in keys] def get_best_code(): '''轉譯用最佳短碼字典''' global dict_cword_best for k in dict_cword.keys(): cand = dict_cword.get(k) #取出其中的候選 lst_t = [] lst_f = [] for code in cand.keys(): if cand[code] == True: lst_t.append('{}:{}'.format(len(code), code)) else: lst_f.append('{}:{}'.format(len(code), code)) if lst_f: #不用選字的碼,優先採用 lst_f.sort() n, dict_cword_best[k] = lst_f[0].split(':', 1) elif lst_t: lst_t.sort() n, dict_cword_best[k] = lst_t[0].split(':') def translate(dic, key): '''轉譯。若無法轉譯,傳回原值''' value = dic.get(key) if value: return value else: return key def try_translate(jam): '''嘗試轉譯可能是中文混雜的字串;不能轉換的部分照原字串傳回''' output = cw = '' #cw: candidate word pos = -1 for i in jam: pos += 1 if i in keys_lst: cw += i else: if cw: output += translate(dict_code, cw) cw = '' output += i if pos == len(jam) - 1: if cw: output += translate(dict_code, cw) return output def xmode(): '''X模式:組字碼轉成字符(指文字、符號等的統稱)''' text = copy_from_clipboard() if text: code_lst = text.split(' ') cword_lst = [] for c in code_lst: w = dict_code.get(c) if w: cword_lst.append(w) else: cword_lst.append(try_translate(c)) copy_to_clipboard(''.join(cword_lst)) def ymode(): '''Y模式:字符轉成組字碼''' text = copy_from_clipboard() if text: cword_lst = [w for w in text] code_lst = [] for w in cword_lst: c = dict_cword_best.get(w) if c: code_lst.append(c + ' ') else: code_lst.append(w) copy_to_clipboard(''.join(code_lst)) def main(): if len(sys.argv) > 1: prepare_dict(code_table) get_best_code() if sys.argv[1] == 'xmode': xmode() elif sys.argv[1] == 'ymode': ymode() if __name__ == '__main__': dict_code = {} #{code: cword},記錄組字碼第一次出現時的字 dict_cword = {} #{cword: code},中介的暫時性字典,用來產生dict_cword_best用 dict_cword_best = {} #{cword: code},字符的最佳短碼:不須選字的最短碼;若無此類碼,則放排序後排在前面的最短碼。 keys_lst = [] #放組字鍵之字元 main() 【使用方法】 以一篇《千字文》做轉譯的範例 這篇內容只是拿來當範例,不同版本,文字有些許差異,這非關本主題 天地玄黃 宇宙洪荒 日月盈昃 辰宿列張 寒來暑往 秋收冬藏 閏餘成歲 律呂調陽 雲騰致雨 露結為霜 金生麗水 玉出崑崗 劍號巨闕 珠稱夜光 果珍李柰 菜重芥薑 海鹹河淡 鱗潛羽翔 龍師火帝 鳥官人皇 始制文字 乃服衣裳 推位讓國 有虞陶唐 吊民伐罪 周發殷湯 坐朝問道 垂拱平章 愛育黎首 臣伏戎羌 遐邇壹體 率賓歸王 鳴鳳在樹 白駒食場 化被草木 賴及萬方 蓋此身髮 四大五常 恭惟鞠養 豈敢毀傷 女慕貞絜 男效才良 知過必改 得能莫忘 罔談彼短 靡恃己長 信使可覆 器欲難量 墨悲絲染 詩讚羔羊 景行維賢 剋念作聖 德建名立 形端表正 空谷傳聲 虛堂習聽 禍因惡積 福緣善慶 尺璧非寶 寸陰是競 資父事君 曰嚴與敬 孝當竭力 忠則盡命 臨深履薄 夙興溫清 似蘭斯馨 如松之盛 川流不息 淵澄取映 容止若思 言辭安定 篤初誠美 慎終宜令 榮業所基 藉甚無竟 學優登仕 攝職從政 存以甘棠 去而益詠 樂殊貴賤 禮別尊卑 上和下睦 夫唱婦隨 外受傅訓 入奉母儀 諸姑伯叔 猶子比兒 孔懷兄弟 同氣連枝 交友投分 切磨箴規 仁慈隱惻 造次弗離 節義廉退 顛沛匪虧 性靜情逸 心動神疲 守真志滿 逐物意移 堅持雅操 好爵自縻 都邑華夏 東西二京 背邙面洛 浮渭據涇 宮殿盤鬱 樓觀飛驚 圖寫禽獸 畫彩仙靈 丙舍傍啟 甲帳對楹 肆筵設席 鼓瑟吹笙 升階納陛 弁轉疑星 右通廣內 左達承明 既集墳典 亦聚群英 杜稾鍾隸 漆書壁經 府羅將相 路俠槐卿 戶封八縣 家給千兵 高冠陪輦 驅轂振纓 世祿侈富 車駕肥輕 策功茂實 勒碑刻銘 磻溪伊尹 佐時阿衡 奄宅曲阜 微旦孰營 桓公匡合 濟弱扶傾 綺迴漢惠 說感武丁 俊乂密勿 多士寔寧 晉楚更霸 趙魏困橫 假途滅虢 踐土會盟 何遵約法 韓弊煩刑 起翦頗牧 用軍最精 宣威沙漠 馳譽丹青 九州禹跡 百郡秦并 嶽宗泰岱 禪主雲亭 雁門紫塞 雞田赤城 昆池碣石 鉅野洞庭 曠遠綿邈 巖岫杳冥 治本於農 務資稼穡 俶載南畝 我藝黍稷 稅熟貢新 勸賞黜陟 孟軻敦素 史魚秉直 庶幾中庸 勞謙謹敕 聆音察理 鑑貌辯色 貽厥嘉猷 勉其祗植 省躬譏誡 寵增抗極 殆辱近恥 林皋幸即 兩疏見機 解組誰逼 索居閑處 沉默寂寥 求古尋論 散慮逍遙 欣奏累遣 慼謝歡招 渠荷的歷 園莽抽條 枇杷晚翠 梧桐早凋 陳根委翳 落葉飄颻 遊鵾獨運 淩摩絳霄 耽讀翫市 寓目囊箱 易輶攸畏 屬耳垣牆 具膳餐飯 適口充腸 飽飫烹宰 饑厭糟糠 親戚故舊 老少異糧 妾御績紡 侍巾帷房 紈扇圓潔 銀燭煒煌 晝眠夕寐 藍筍象床 弦歌酒讌 接杯舉觴 矯手頓足 悅豫且康 嫡後嗣續 祭祀烝嘗 稽顙再拜 悚懼恐惶 牋牒簡要 顧答審詳 骸垢想浴 執熱願涼 驢騾犢特 駭躍超驤 誅斬賊盜 捕獲叛亡 布射僚丸 嵇琴阮嘯 恬筆倫紙 鈞巧任釣 釋紛利俗 並皆佳妙 毛施淑姿 工顰妍笑 年矢每催 曦暉朗曜 璇璣懸斡 晦魄環照 指薪修祜 永綏吉劭 矩步引領 俯仰廊廟 束帶矜莊 徘徊瞻眺 孤陋寡聞 愚蒙等誚 謂語助者 焉哉乎也 先將《千字文》內容複製到剪貼板 用命令直通車執行ymode,將結果貼出來 edn yal lwa ka nuj niq wrb rfs do ue ruf dlb fkn nptd dri qek njb ln dho mk hfn gpx pba rrv mke xat ay zs mie opo ino bm uta ubnf ppx ua ulo syo bf utm ae se la wn kaa eei edb enx acr ol ffe mbei ksb hy lx ser qtn kbm tzj trsv ret gq rbr reqe wm zoxk wto wff ufmc kd eee bhee akp ren fn lnn nfa nbo bn pdk guo snr wx nzj rp uu lkn snok jve ple ik ohe x zoed bni leo onj oxx paq us no fx feyu wep bby jue moo hwn ge jrb pj ldj hx tue hw ho re pad aqj bkr offw nsw ,de qd ljj nbv pq ke onf rnf xy tua pdo mfno xn yep pfl vpx rdj tn vb pux ru fy rce zfl sx vax f dn w sn rbf hv rcnm kx ede irp gu pvd gx rddf zmb fds qdx lxd up an vdo qow hp flp dd ul rdd fha nbf iff mip vdd ltte hya gg kn pio pc to cv om win rcv deq qfy qt ssa wkt iya iq bkf bhj ds mv sve rumb jorrv ayh pvf rok mh ewn coo le kmp ldi vk ez nbi wo pqa yc zfe sy ed rh ct od oha hb rq sq bv ldn cnn pka rs nka aa bue jn lr bb bxx jce eoo dov ox ea nx ypz so ldlv dx cha mbr cnb aop rv wnn cg xr rda seb wdf whu pub bse kbk yhd goo tbu az afe si wl ba pmh whi wjd rux dcn nwo ze roo qha io ej ng nz zmf vdp iay bkd hjb spb nme api ft fr fki ky xd kl vf ldr snz pyx jde pyv jrv rob mz ezp xz u go snot yua ri y iun rn dsb qa mbk rsl odr bea pqg fe hoo fa mqu qnn odd gej xw cpa enu pia isi bp fnq oma pbx xg gjo ppd fsu qak zj bl grl zll hk orl tp neo km cwn tju lxx xux jru bdp cdp ltto zko ql pre bav bh hmbr sow bin vj lav rpi bx lpq dkw jbt wln fs zk hse hz hhu nw ha gd rsi lbp naa jba yha m eqw snm ldh hcc ruy jya xve xt gz efaa pm lttsr yb oclv aj tmp csa co r los ffu fbiv tj wpo wez wquv jzn wsi nov cu zf twum tg rmr fj hls ot nf bla odv eqe em pei ef enb bgo pgy fop qi nek a truf ,df zpzw iru lrn yuv kkhp oin zse xj bd snb bbyv urj cqa fz dse xoo t lka nbn xie ywn wsj due dl vt yja fba lfa ruq eh rcn tye qhn agq twv wgw asj cy ssi lpa fsv gea tm lo pgn tvav dgi fp yya b ms neq sao gj kv q kc blo qaqc mxv yncu jfk ssg sl rscw pcc fq cj dfv ucl csi zjn idx rpv nbd ry lopg lhr aco lomq ce pex ex pxi h bto ut xl ngl fo pbjv rz dev lzz ff tede bua fke aoo wwh qb jqn pft svo ohw wrc jh ir ah we ti phx xxv xe nm cca ye ndez nti efed tz tx uuv yzsu hgv otn tka pox bhw efn eazr ozk yv ad duf pto bw sna wu jwj brj fta kri yl beer pta spx nqj ncj dru mhu cf ag wsp wdv mav eio nae hue k yy pcnu if tdo eob fnh bkj eqid ns fnw paxe rso ake uta lnt lpv mi zfs ny evv qo yfa yay dbl wal lod loo aff qui wneo lkw dlk yw spj eqgw eop eiq tdov ndl wuo tej fbb ffk mpd bb hneq hwoo pfsu jc n lqo ix rt hbw hqbp hr lf imb li rdx kt qfee bzs zfev ctov lzp hsa cx ufa ges je lrf gb ci lenq rnd iqn irc vsd rap ldo nja kq af erv lil dcl mbuo lbei yq bead edx kba rsxe tje sm sqk irl irv nal ybo jlr tk duo fka kwn rha ttn pddj yj gi eb ysv mrl g nbh sme ive ew jns cjo mtv zv wnr qf nuv nem na joo eaa iam rup zh suw uw kin fnv qsa uc aqphv isa rin jdo wfft rpto d ldx ok rdr jiq pn tbl tcl dr eejj two tneo djj bno bcs tdk hgx fvder ro rst ccv unc fwn dbnf qc ncw wybp lhv sps usu rkl ib eepr ni nqnu mo vkv ztm ep cber pip qkn cc rj yede gwoo meb ubho zn xlu gow oo tl uep xnl xgn lwf nlj xwb yn mrfd mlew ll as jx rg ypf sp qrb man lgx mpv sg sfy pya nj nve ffy ska fee ob wyo adk fca fwj fpdk cnde mox ca ngqb rrf zex nn ltn qlw tiv weo irff jlg tba eq nvd vdg hj eta ozn hf unn me lew gxo i ome sb ja rsol wefr snt hakd uuub ey hfj hvs qv ih hpdk pkxr pst zmd v fb zao nii ibh qulh yfo th wwo yz yf yt bls mffr mfqs sjmv sya mflh ovv yo mflk isb cki mjv bif jij qu blu fl xni saa pla zx hake kyv brr oeh hgo zej pam sxx anr ikk pke ana mg sbd hri pwo be bpd ve gsp ml fva su big ie zstg gkj zed vsj vdn vm pev dbkk dncv aue dvv kzv krz muh jbdv dvom pdv kk df jfd rli pp rsjo un seg yoo dod vfv zsp qii apt pav pfp lab liq jcs fnn may rgy mirs mioo mvo mra zg bel ntdd mrj qh qq zya isu iqu iwo mdx hov ezkf jaqo hjv al 將上述字碼複製到剪貼板 用命令直通車執行xmode,將結果貼出來,因與前述《千字文》內容一樣,這裡就不再貼一次 【補充說明】 對這個執行結果做一些補充說明 一、如果純中文的文章轉成字碼,再轉回中文文章,若出現與原來不一樣的字,大概就是那些字輸入時需要選字,而轉譯的過程中,選了順序在前的不同字 二、這裡看到轉來又轉去,兩份中文的內容都一樣,似乎這千字都不需選字?這是因輸入法的碼表將選字碼也設計進去了,對於熟悉的人,是好像不選字般。若去掉這層,這千字中有22個需要選字,選字率為2.2%。這可利用「偽.蝦米」較為精細的解譯功能看出來,但我裝給它用的二進制碼表是較早的版本,並不是目前最新的版本 三、選字率要多低,效果才會好?這點自己沒去研究,也沒切確的數字,可能直接試試轉譯結果滿不滿意,若不滿意大概也代表了選字率較為偏高。上述文章有一些現代不常用到的字,若是常用字,選字率應該還會更低 四、要轉譯的內容若為中英文混雜,可能會導致非預期結果 五、這範列中雖沒一般的標點符號,但所用輸入法碼表中也含有標點符號,故也可轉譯 以上的作法可能有些狀況沒有考慮到,不見得是週全嚴謹的作法,只是權充需要的人參考 程式碼也是粗略撰寫,要用在不同環境,要做適度調整 |
|