跳到主要內容

MikroTik 的 中文註解亂碼解決方法

 自從去年臨時換成MikroTik路由器後,功耗和效能都非常滿意,臺灣代理商送來時就有預設的Firewall Rules,完全沒有問題,唯一的不滿就是註解在網路介面看到時是亂碼,詢問代理商說要用 WinBox v3 Windows 版本才能正常顯示註解。WinBox v3還有另一個問題,在高解析度螢幕上文字非常小。

我在家使用的主力是 mac 和 Linux,我也不喜歡使用 WinBox,能夠使用瀏覽器才方便。

雖然沒有太多時間去研究,但基本上所有的路由器都可以匯出文字,所以找Gemini討論。首先,Gemini教我如何匯出,開啟 Terminal,輸入

 export  file=my_config

接下來會在 Files 看到 my_config.rsc ,這是純文字的指令,其中會有Big5中文編碼後的註解

 add action=accept chain=input comment="\B6\B6\A7\C7\A6\EC\B8m\A5\B2\B6\B7\A9T\
    \A9w--> \B6\B6\A7\C70  (\A9\F1\A6\E6\A6\A8\A5\\\B5n\A4J\AB\E1\AA\BAIP)" \
    dst-port=21,22,23,8291 protocol=tcp src-address-list=login-ok

轉換成UTF-8應該是以下這樣,利用新版WinBox貼上註解後也證實如此。

 add action=accept chain=input comment="\E9\A0\86\E5\BA\8F\E4\BD\8D\E7\BD\AE\E5\BF\85\E9\A0\88\E5\9B\BA\E5\AE\9A\2D\2D\3E\20\E9\A0\86\E5\BA\8F\30\20\20\28\E6\94\BE\E8\A1\8C\E6\88\90\E5\8A\9F\E7\99\BB\E5\85\A5\E5\BE\8C\E7\9A\84\49\50\29" \
    dst-port=21,22,23,8291 protocol=tcp src-address-list=login-ok

在 MikroTik 的 .rsc 檔案中,當字串包含非 ASCII 字元(如中文)時,它會用 \XX 的格式來表示。其中註解文字應為:順序位置必須固定--> 順序0 (放行成功登入後的IP)

所以我們要做的事情就是把這個檔案編碼改為UTF-8, 存檔後刪除原有設定,再重新匯入設定檔。

/import file-name=my_config_utf8.rsc verbose=yes

所以在與雙子座多輪對話後,寫出一支轉換 my_config.rsc 變為 my_config_utf8.rsc 的程式,這程式還會列出修改的中文字, 對於不敢直接覆蓋原檔案,可手動修改註解。

 import re
import os

def big5_hex_to_utf8_hex(mt_str):
    """將 MikroTik 的 Big5 混合編碼轉換為 UTF-8 的 Hex 轉義格式"""
    # 移除斷行連接符號
    cleaned_str = re.sub(r'\\\s*[\r\n]+\s*', '', mt_str)
    
    result_bytes = bytearray()
    i = 0
    while i < len(cleaned_str):
        if cleaned_str[i] == '\\':
            if i + 1 < len(cleaned_str) and cleaned_str[i+1] == '\\':
                result_bytes.append(ord('\\'))
                i += 2
            elif i + 2 < len(cleaned_str) and re.match(r'[0-9A-Fa-f]{2}', cleaned_str[i+1:i+3]):
                hex_val = int(cleaned_str[i+1:i+3], 16)
                result_bytes.append(hex_val)
                i += 3
            else:
                result_bytes.append(ord('\\'))
                i += 1
        else:
            result_bytes.append(ord(cleaned_str[i]))
            i += 1
    
    try:
        # 關鍵轉換:Big5 -> String -> UTF-8 Bytes -> Hex String
        chinese_str = result_bytes.decode('big5')
        utf8_bytes = chinese_str.encode('utf-8')
        return "".join(f"\\{b:02X}" for b in utf8_bytes)
    except:
        return mt_str

def process_final(input_file):
    output_file = input_file.replace('.rsc', '_utf8.rsc')
    report_file = input_file.replace('.rsc', '_report.txt')
    
    if not os.path.exists(input_file):
        print(f"找不到檔案: {input_file}")
        return

    with open(input_file, 'r', encoding='ascii', errors='ignore') as f:
        full_content = f.read()

    report = [f"=== MikroTik 轉換對照報告 (UTF-8 Hex + 路徑上下文) ===", 
              f"{'指令區塊 (Context Path)':<40} | {'屬性':<10} | {'轉換後中文內容'}", "-" * 110]
    
    current_path = "/"
    lines = full_content.splitlines()
    output_lines = []
    
    i = 0
    while i < len(lines):
        line = lines[i]
        
        # 追蹤當前區塊路徑 (如 /ip firewall filter)
        path_match = re.match(r'^/([a-zA-Z0-9\-\s]+)', line)
        if path_match:
            current_path = path_match.group(0).strip()
        
        # 處理跨行屬性 (抓取完整的引號內容)
        combined_line = line
        temp_idx = i
        while (combined_line.count('"') % 2 != 0 or combined_line.endswith('\\')) and temp_idx + 1 < len(lines):
            temp_idx += 1
            combined_line += "\n" + lines[temp_idx]
        
        # 尋找引號內容並取代
        attr_pattern = re.compile(r'(\w+)="([\s\S]*?)"')
        new_combined_line = combined_line
        
        matches = list(attr_pattern.finditer(combined_line))
        for m in reversed(matches):
            key, val = m.groups()
            if '\\' in val:
                utf8_hex = big5_hex_to_utf8_hex(val)
                if utf8_hex != val:
                    # 為了報告好讀,我們在這裡反解出中文
                    try:
                        readable_chinese = bytes.fromhex(utf8_hex.replace('\\', '')).decode('utf-8')
                    except:
                        readable_chinese = "解碼失敗"

                    report.append(f"{current_path[:40]:<40} | {key:<10} | {readable_chinese[:50]}")
                    
                    start, end = m.span()
                    new_combined_line = new_combined_line[:start] + f'{key}="{utf8_hex}"' + new_combined_line[end:]
        
        output_lines.append(new_combined_line)
        i = temp_idx + 1

    # 儲存
    with open(output_file, 'w', encoding='ascii') as f:
        f.write('\n'.join(output_lines))
    with open(report_file, 'w', encoding='utf-8') as f:
        f.write('\n'.join(report))

    print(f"[*] 處理完畢!")
    print(f"    - 匯入用檔案: {output_file} (已轉為 UTF-8 Hex)")
    print(f"    - 對照報告: {report_file} (含路徑上下文)")

if __name__ == "__main__":
    process_final('my_config.rsc')

留言

這個網誌中的熱門文章

DBeaver 介面語言

DBeaver是我個人頗常用的一套跨平台Database管理工具,最近升級後發現Windows版本居然變成簡體中文,而且無法切換為英文。

Personal Bookmark

Java SE 6 + Firefox 2 UI 問題 As I do . Google拋棄了了SOAP API,浮想聯翩 https://www.gandi.net/ VS 2005 SP1中文版推出 Windows Vista中文版下載 ASP.NET 2.0網頁執行管線與快取原理 Cache 2.0快取架構與快取資料自動移除架構圖 flickr sync 分享與試用 SUN Looking Glass 3D圖形介面發布1.0 雅虎勵精圖治推動改革 Wait and see 國內某SOC疑遭駭客入侵 大砲開講 Very Important! 微軟公佈Vista安全程式介面草案 一窺Google開原碼庫房乾坤 qing is writing a dig girl net... wait and see

自然人憑證讀卡機驅動程式

鳥毅用的是第一代的自然人憑證讀卡機,EZ100PU(後來有同事買EZmini可以讀SIM卡似乎更好),每年報稅時用一次。 本來只是要申請些政府業務,一時之間找不到光碟,沒想到在 驅動程式下載 居然看到Linux和Mac的驅動程式,剩下的就是政府單位的網頁和程式應該改版了吧!!!