using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace _0_Framework.Application; /// /// نحوه‌ي تبديل اعداد /// public enum IranSystemNumbers { /// /// اعداد موجود به فرمت ايران سيستم تبديل نشوند و به همان شكل اصلي باقي بمانند /// DontConvert, /// /// اعداد موجود هم به قالب ايران سيستم تبديل شوند /// 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 _charMapperCharIsNotFinal = new Dictionary { {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 _charMapperNextCharFinal = new Dictionary { {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 _charMapperPreviousCharFinal = new Dictionary { {195, 144},//أ {197, 144},//إ {199, 144},//ا {201, 251},//ة {218, 228},//ع {219, 232},//غ {229, 251},//ه {170, 251}//ﻫ }; private static readonly IDictionary _charMapperPreviousCharNextCharFinal = new Dictionary { {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("ءآأؤإادذرزژو"); /// /// تبديل رشته‌ي يونيكد به رشته‌ي ايران سيستمي /// /// رشته‌ي يونيكد /// تبديل اعداد /// رشته‌ي ايران سيستمي 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 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(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(); } }