using System;
using System.Collections.Generic;
using System.Text;
namespace JXHelper.Core
{
///
/// Bộ chuyển đổi mã ký tự TCVN3 (ABC) sang Unicode chuẩn cho game Võ Lâm Truyền Kỳ 1.
///
public static class Tcvn3Encoding
{
private static readonly Dictionary TcvnToUnicodeMap = new()
{
// Chữ thường có dấu
{ 0xb8, 'à' }, { 0xb5, 'á' }, { 0xb6, 'ả' }, { 0xb7, 'ã' }, { 0xb9, 'ạ' },
{ 0xa8, 'ă' }, { 0xbb, 'ằ' }, { 0xbe, 'ắ' }, { 0xbc, 'ẳ' }, { 0xbd, 'ẵ' }, { 0xc6, 'ặ' },
{ 0xa9, 'â' }, { 0xc7, 'ầ' }, { 0xca, 'ấ' }, { 0xc8, 'ẩ' }, { 0xc9, 'ẫ' }, { 0xcb, 'ậ' },
{ 0xcc, 'è' }, { 0xd0, 'é' }, { 0xce, 'ẻ' }, { 0xcf, 'ẽ' }, { 0xd1, 'ẹ' },
{ 0xaa, 'ê' }, { 0xd2, 'ề' }, { 0xd5, 'ế' }, { 0xd3, 'ể' }, { 0xd4, 'ễ' }, { 0xd6, 'ệ' },
{ 0xd7, 'ì' }, { 0xdd, 'í' }, { 0xd8, 'ỉ' }, { 0xdc, 'ĩ' }, { 0xde, 'ị' },
{ 0xdf, 'ò' }, { 0xe3, 'ó' }, { 0xe1, 'ỏ' }, { 0xe2, 'õ' }, { 0xe4, 'ọ' },
{ 0xab, 'ô' }, { 0xe5, 'ồ' }, { 0xe8, 'ố' }, { 0xe6, 'ổ' }, { 0xe7, 'ỗ' }, { 0xe9, 'ộ' },
{ 0xac, 'ơ' }, { 0xea, 'ờ' }, { 0xed, 'ớ' }, { 0xeb, 'ở' }, { 0xec, 'ỡ' }, { 0xee, 'ợ' },
{ 0xef, 'ù' }, { 0xf3, 'ú' }, { 0xf1, 'ủ' }, { 0xf2, 'ũ' }, { 0xf4, 'ụ' },
{ 0xad, 'ư' }, { 0xf5, 'ừ' }, { 0xf8, 'ứ' }, { 0xf6, 'ử' }, { 0xf7, 'ữ' }, { 0xf9, 'ự' },
{ 0xfa, 'ỳ' }, { 0xfd, 'ý' }, { 0xfb, 'ỷ' }, { 0xfc, 'ỹ' }, { 0xfe, 'ỵ' },
{ 0xa7, 'đ' }, { 0xa1, 'Đ' },
// Chữ hoa có dấu (trong bảng mã TCVN3, ký tự hoa có dấu thường ghép hoặc mã đặc biệt)
{ 0x80, 'À' }, { 0x81, 'Á' }, { 0x82, 'Ả' }, { 0x83, 'Ã' }, { 0x84, 'Ạ' },
{ 0x85, 'Ă' }, { 0x86, 'Ằ' }, { 0x87, 'Ắ' }, { 0x88, 'Ẳ' }, { 0x89, 'Ẵ' }, { 0x8a, 'Ặ' },
{ 0x8b, 'Â' }, { 0x8c, 'Ầ' }, { 0x8d, 'Ấ' }, { 0x8e, 'Ẩ' }, { 0x8f, 'Ẫ' }, { 0x90, 'Ậ' },
{ 0x91, 'È' }, { 0x92, 'É' }, { 0x93, 'Ẻ' }, { 0x94, 'Ẽ' }, { 0x95, 'Ẹ' },
{ 0x96, 'Ê' }, { 0x97, 'Ề' }, { 0x98, 'Ế' }, { 0x99, 'Ể' }, { 0x9a, 'Ễ' }, { 0x9b, 'Ệ' },
{ 0x9c, 'Ì' }, { 0x9d, 'Í' }, { 0x9e, 'Ỉ' }, { 0x9f, 'Ĩ' }, { 0xa0, 'Ị' },
};
///
/// Giải mã mảng byte TCVN3 thành chuỗi Unicode chuẩn.
///
public static string Decode(byte[] bytes, int offset = 0, int length = -1)
{
if (bytes == null || bytes.Length == 0) return string.Empty;
if (length < 0) length = bytes.Length - offset;
int end = Math.Min(bytes.Length, offset + length);
var sb = new StringBuilder(length);
for (int i = offset; i < end; i++)
{
byte b = bytes[i];
if (b == 0) break; // Ký tự kết thúc chuỗi null-terminator
if (TcvnToUnicodeMap.TryGetValue(b, out char unicodeChar))
{
sb.Append(unicodeChar);
}
else if (b >= 32 && b < 127)
{
sb.Append((char)b);
}
else
{
// Giữ nguyên hoặc bỏ qua ký tự không in được
sb.Append((char)b);
}
}
return sb.ToString().Trim();
}
///
/// Chuyển đổi chuỗi ký tự TCVN3 (hoặc chuỗi ANSI đọc nhầm) sang Unicode chuẩn.
///
public static string ToUnicode(string text)
{
if (string.IsNullOrEmpty(text)) return string.Empty;
var sb = new StringBuilder(text.Length);
foreach (char c in text)
{
byte b = (byte)(c & 0xFF);
if (c <= 0xFF && TcvnToUnicodeMap.TryGetValue(b, out char unicodeChar))
{
sb.Append(unicodeChar);
}
else
{
sb.Append(c);
}
}
return sb.ToString();
}
}
}