Files
Backend-Api/0_Framework/Application/ConvertToIranSystem.cs
2024-07-05 21:36:15 +03:30

365 lines
10 KiB
C#
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace _0_Framework.Application;
/// <summary>
/// نحوه‌ي تبديل اعداد
/// </summary>
public enum IranSystemNumbers
{
/// <summary>
/// اعداد موجود به فرمت ايران سيستم تبديل نشوند و به همان شكل اصلي باقي بمانند
/// </summary>
DontConvert,
/// <summary>
/// اعداد موجود هم به قالب ايران سيستم تبديل شوند
/// </summary>
Convert
}
public static class ConvertToIranSystem
{
const byte AlefChasban = 145;
const byte LaaArabic = 242;
const byte LaamAvval = 243;
const byte QuestionMark = 191;
private static readonly IDictionary<byte, byte> _charMapperCharIsNotFinal =
new Dictionary<byte, byte>
{
{48 , 128}, // 0
{49 , 129}, // 1
{50 , 130}, // 2
{51 , 131}, // 3
{52 , 132}, // 4
{53 , 133}, // 5
{54 , 134}, // 6
{55 , 135}, // 7
{56 , 136}, // 8
{57 , 137}, // 9
{161, 138}, // ،
{191, 140}, // ؟
{193,143}, //
{194,141}, // آ
{195,145}, //
{196, /*248*/ 142}, //
{197,145}, //
{198,254}, //
{199,145}, //
{200,147}, //
{201,250}, //
{202,151}, //
{203,153}, //
{204,155}, //
{205,159}, //
{206,161}, //
{207,162}, //
{208,163}, //
{209,164}, //
{210,165}, //ز
{211,168}, //
{212,170}, //
{213,172}, //
{214,174}, //
{216,175}, //
{217,224}, //
{218,227}, //
{219,231}, //
{220,139}, // -
{221,234}, //
{222,236}, //
{223,238}, //
{225,243}, //
{227,245}, //
{228,247}, //
{229,250}, //
{230,248}, //
{236,254}, //
{237,254}, //
{129,149}, //
{141,157}, //
{142,166}, //
{152,238}, //
{144,240} //
};
private static readonly IDictionary<byte, byte> _charMapperNextCharFinal =
new Dictionary<byte, byte>
{
{198, 252}, //
{200, 146}, //
{201, 249}, //
{202, 150}, //
{203, 152}, //
{204, 154}, //
{205, 158}, //
{206, 160}, //
{211, 167}, //
{212, 169}, //
{213, 171}, //
{214, 173}, //
{218, 226}, //
{219, 230}, //
{221, 233}, //
{222, 235}, //
{223, 237}, //
{225, 241}, //
{227, 244 /*245*/}, //
{228, 246}, //
{229, 249}, //
{236, 252}, //
{237, 252}, //
{129, 148}, //
{141, 156}, //
{142, 166}, //
{152, 237}, //
{144, 239} //
};
private static readonly IDictionary<byte, byte> _charMapperPreviousCharFinal =
new Dictionary<byte, byte>
{
{195, 144},//أ
{197, 144},//إ
{199, 144},//ا
{201, 251},//ة
{218, 228},//ع
{219, 232},//غ
{229, 251},//ه
{170, 251}//
};
private static readonly IDictionary<byte, byte> _charMapperPreviousCharNextCharFinal =
new Dictionary<byte, byte>
{
{195, 144}, // أ
{197, 144}, //إ
{199, 144},//ا
{200, 146}, //ب
{201, 249}, //ة
{202, 150}, //ت
{203, 152}, //ث
{204, 154}, //ﺝ
{205, 158}, //ﺡ
{206, 160}, //ﺥ
{211, 167},//س
{212, 169},//ش
{213, 171}, //ص
{214, 173}, //ض
{218, 225}, //ع
{219, 229}, //غ
{221, 233},//ف
{222, 235},//ق
{223, 237},//ك
{225, 241},//ل
{227, 244},//م
{228, 246},//ن
{229, 249},//ه
{236, /*253*/ 252},//ى
{237, 253},//ی
{129, 148},//پ
{141, 156},//چ
{152, 237},//ک
{144, 239}//گ
};
private static readonly Encoding _encoding1256 = Encoding.GetEncoding("windows-1256");
private static readonly byte[] _singles = _encoding1256.GetBytes("ءآأؤإادذرزژو");
/// <summary>
/// تبديل رشته‌ي يونيكد به رشته‌ي ايران سيستمي
/// </summary>
/// <param name="text">رشته‌ي يونيكد</param>
/// <param name="iranSystemNumbers">تبديل اعداد</param>
/// <returns>رشته‌ي ايران سيستمي</returns>
public static string ToIranSystem(
this string text,
IranSystemNumbers iranSystemNumbers = IranSystemNumbers.DontConvert)
{
if (string.IsNullOrWhiteSpace(text))
{
return text;
}
////var array = iranSystemBytes.ToArray();
////string s = Encoding.GetEncoding(1256).GetString(array);
////byte[] Utf8Data = Encoding.UTF8.GetBytes(s);
text = reverseNumbersAndLetters(text);
var iranSystemBytes = getUnicodeToIranSystem(text, iranSystemNumbers);
var iranSystemText = _encoding1256.GetString(iranSystemBytes.ToArray()).Trim();
char last_char = text[text.Length - 1];
if (last_char == 'خ')
{
iranSystemText = iranSystemText + " ";
}
return new string(iranSystemText.Reverse().ToArray());
}
private static byte getLattinLetter(byte c)
{
return char.IsNumber((char)c) ? (byte)(c + 80) : getMirroredCharacter(c);
}
private static byte getMapperCharIsNotFinal(byte currentChar)
{
byte value;
return _charMapperCharIsNotFinal.TryGetValue(currentChar, out value) ? value : currentChar;
}
private static byte getMapperNextCharFinal(byte currentChar)
{
byte value;
return _charMapperNextCharFinal.TryGetValue(currentChar, out value) ? value : getMapperCharIsNotFinal(currentChar);
}
private static byte getMapperPreviousCharFinal(byte currentChar)
{
byte value;
return _charMapperPreviousCharFinal.TryGetValue(currentChar, out value) ? value : getMapperCharIsNotFinal(currentChar);
}
private static byte getMapperPreviousCharNextCharFinal(byte currentChar)
{
byte value;
return _charMapperPreviousCharNextCharFinal.TryGetValue(currentChar, out value) ? value : getMapperCharIsNotFinal(currentChar);
}
private static byte getMirroredCharacter(byte c)
{
switch (c)
{
case (byte)'(': return (byte)')';
case (byte)'{': return (byte)'}';
case (byte)'[': return (byte)']';
case (byte)')': return (byte)'(';
case (byte)'}': return (byte)'{';
case (byte)']': return (byte)'[';
default: return c;
}
}
private static List<byte> getUnicodeToIranSystem(string text, IranSystemNumbers iranSystemNumbers)
{
var unicodeString = string.Format(" {0} ", text);
var textBytes = _encoding1256.GetBytes(unicodeString);
byte pre = 0;
var length = textBytes.Length;
var results = new List<byte>(length);
for (var i = 0; i < length; i++)
{
byte cur;
var currentChar = textBytes[i];
if (isNumber(currentChar) && iranSystemNumbers == IranSystemNumbers.DontConvert)
{
cur = currentChar;
results.Add(cur);
pre = cur;
}
else if (isLattinLetter(currentChar))
{
cur = getLattinLetter(currentChar);
results.Add(cur);
pre = cur;
}
else if (i != 0 && i != length - 1)
{
cur = getUnicodeToIranSystemChar(textBytes[i - 1], currentChar, textBytes[i + 1]);
if (cur == AlefChasban) // برای بررسی استثنای لا
{
if (pre == LaamAvval)
{
results.RemoveAt(results.Count - 1);
results.Add(LaaArabic);
}
else
{
results.Add(cur);
}
}
else
{
results.Add(cur);
}
pre = cur;
}
}
return results;
}
private static byte getUnicodeToIranSystemChar(byte previousChar, byte currentChar, byte nextChar)
{
var isPreviousCharFinal =
isWhitespaceOrLattinOrQuestionMark(previousChar) ||
isFinalLetter(previousChar);
var isNextCharFinal = isWhitespaceOrLattinOrQuestionMark(nextChar);
if (isPreviousCharFinal && isNextCharFinal)
{
return getMapperPreviousCharNextCharFinal(currentChar);
}
if (isPreviousCharFinal)
{
return getMapperPreviousCharFinal(currentChar);
}
if (isNextCharFinal)
{
return getMapperNextCharFinal(currentChar);
}
return getMapperCharIsNotFinal(currentChar);
}
private static bool isFinalLetter(byte c)
{
return _singles.Contains(c);
}
private static bool isLattinLetter(byte c)
{
return c < 128 && c > 31;
}
private static bool isNumber(byte currentChar)
{
return currentChar >= 48 && currentChar <= 57;
}
private static bool isWhiteSpaceLetter(byte c)
{
return c == 8 || c == 09 || c == 10 || c == 13 || c == 27 || c == 32 || c == 0;
}
private static bool isWhitespaceOrLattinOrQuestionMark(byte c)
{
return isWhiteSpaceLetter(c) || isLattinLetter(c) || c == QuestionMark;
}
private static string reverseNumbersAndLetters(string text)
{
return Regex.Replace(text, @"[a-zA-Z0-9]+", match =>
{
return new string(match.Value.Reverse().ToArray());
}).Trim();
}
}