Jump to content
Ropedann

Decoder LUA -> Text и Text -> LUA

Recommended Posts

Всем привет, многие знают что я пишу некий Server Manager. Для упращения работы с сервером и его разработки.

И в процессе я сталкнулся с такой задачей.

Как все знают Сервер с Кририлицей работает не очень хорошо.

И многие прибегают к кодированию Русского текста в байткод.

Типа токого:

\196\238\225\240\238 \239\238\230\224\235\238\226\224\242\252!

Существует программа которая помогает разработчикам в кодировании и дикодировании этого.

 

Но задача Server Manager Объеденить весь этот софт в одном приложении.

И так перейдем к сути.

 

С толкнулся я с тем что не могу разобраться в данной строке.

Понятно что она основывается на таблице ASCII

И написав вот такой небольшой код на C# У меня получилось адекватно декадировать данную строку.

        static void Main(string[] args)
        {
            string LuaText = @"\196\238\225\240\238 \239\238\230\224\235\238\226\224\242\252!";
            byte[] buffer = new byte[] { 196, 238, 225, 240, 238, 32, 239, 238, 230, 224, 235, 238, 226, 224, 242, 252 };
            Console.WriteLine(DecoderLua(buffer));
        }

        public static string DecoderLua(byte[] byteArray)
        {
            return System.Text.Encoding.GetEncoding(1251).GetString((byteArray));
        }

Вывод в консоль:

image.png.c9dfb842ed22ebe9391a155570ac032b.png

 

не смог придумать адекватного способа избавляться от '\' - слэшэй и простовлять пробелы.

Может быть есть какаято библиотека для работы с подобными строками.

Так как штатными методами по типу replace, split и.д. особо выходит.

 

Зарание спасибо за помощь.

Edited by Ropedann

Share this post


Link to post
Share on other sites

разобрался можно закрывать..

 

Если кому интересно получилось вот так:
 

static void Main(string[] args)
        {
            string LuaText = @"\206\240\243\230\232\229 \209\236\229\240\242\232"; // Входная строка
            char[] a = LuaText.ToCharArray(); // Переводим строку в массив символов
            List<byte> bytes = new List<byte>(); // Создаем массив байт
            string chars = ""; // создаем переменную для запеси символов
            for (int i = 0; i < a.Length; i++) // Проходим в цикле по массиву символов
            {
                if (Char.IsNumber(a[i]) && a[i] != '\\') // Если символ равен числу И НЕ РАВЕН \ то записываем его в переменную chars
                {
                    chars += a[i];
                }
                else if (Char.IsWhiteSpace(a[i])) // Если символ является пробелом то записываем сразу в массив байт
                {
                    bytes.Add(Convert.ToByte(a[i]));
                }
                else if (Char.IsPunctuation(a[i]) && a[i] != '\\') // Если символ является знаком пунктуации то сразу записываем в массив байт
                {
                    bytes.Add(Convert.ToByte(a[i]));
                }
                if (chars.Length == 3) // Доп условие если длина переменной равна 3 то конвертируем ее в байт и записываем в массив поле очищаяем.
                {
                    byte t = Convert.ToByte(chars);  
                    bytes.Add(t);
                    chars = "";
                }
            }
            Console.WriteLine(DecoderLua(bytes.ToArray())); // Вызываем метод перевода массива байтов в символы
        }

        public static string DecoderLua(byte[] byteArray)
        {
            return System.Text.Encoding.GetEncoding(1251).GetString((byteArray)); // Переводим массив байтов в символы
        }

 

Код костыльный но вроде рабочий(Ну и над названием переменных поработать нужно)

Edited by Ropedann
  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Полный код с кодирование и декодированием
 

static void Main(string[] args)
        {
            string LuaText = @"\206\240\243\230\232\229 \209\236\229\240\242\232";
            string TextLua = @"<t> Добро Пожаловать!<n><t>Приходи ко мне, если у тебя есть вопросы относительно классов персонажей. И обдумывай свой выбор по мнению кем быть.<n><t>Ещё я хочу тебе поведать где продаётся неплохое оружие в <pАтланте>.<n><t>Теперь когды ты поднимаешь драгоценные уровни нажимай клавиши Ctrl + A, для того чтобы зайти в окно своих характеристик. Каждый поднятый тобой уровень даёт тебе очки характеристик. <n><t>У тебя в расположении имеется 5 видов антрибутов, таких как: Сила ,которая увеличивает твою атаку в ближнем бою; Ловкость, которая увеличивает твою скорость боя и уворот; Точность, которая увеличивает твоё шанс на попадение и усиливает твою мощь; Дух, который увеличивает твой максимальноый запас маны и магический урон;И Телесложение, которое увеличивает твой запас жизни и Брони.";

            char[] a = LuaText.ToCharArray();
            char[] charTextLua = TextLua.ToCharArray();

            List<byte> bytes = new List<byte>();
            byte[] bytesTextLua = System.Text.Encoding.GetEncoding(1251).GetBytes(charTextLua);

            string chars = "";
            for (int i = 0; i < a.Length; i++)
            {
                if (Char.IsNumber(a[i]) && a[i] != '\\')
                {
                    chars += a[i];
                }
                else if (Char.IsWhiteSpace(a[i]))
                {
                    bytes.Add(Convert.ToByte(a[i]));
                }
                else if (Char.IsPunctuation(a[i]) && a[i] != '\\')
                {
                    bytes.Add(Convert.ToByte(a[i]));
                }
                if (chars.Length == 3)
                {
                    byte t = Convert.ToByte(chars);  
                    bytes.Add(t);
                    chars = "";
                }
            }
            Console.WriteLine(DecoderLua(bytes.ToArray()));

            foreach (var item in CoderLua(charTextLua))
            {
                Console.Write(item);
            }
        }

        public static string DecoderLua(byte[] byteArray)
        {
            return System.Text.Encoding.GetEncoding(1251).GetString((byteArray));
        }

        public static string[] CoderLua(char[] charArray)
        {
            byte[] byteArray = System.Text.Encoding.GetEncoding(1251).GetBytes(charArray);
            List<string> strList = new List<string>();
            for (int i = 0; i < byteArray.Length; i++)
            {
                strList.Add("\\");
                strList.Add(byteArray[i].ToString());
            }
            return strList.ToArray();
        }
    }

 

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Хочу выложить своё решение на языке C++:

#include <iostream>
#include <string>

// Lua strings coder class
class Coder
{
    public:

        // Encode a string
        static std::string encode(const std::string& src)
        {
            // Check that given string is empty
            if (src.empty() == true)
            {
                return src;
            }

            // The result string
            std::string str{ "" };

            // Encode the string
            for (char const& c : src)
            {
                // Get character ascii code
                unsigned int ascii = static_cast<unsigned int>(
                    static_cast<unsigned char>(c)
                );

                // Check the ascii code
                if ( (ascii >= 192 && ascii <= 255) || (ascii == 168) || (ascii == 184) ) // From 'А' to 'я'
                {
                    // Encode the character
                    str.push_back('\\');
                    str.append(std::to_string(ascii));
                }
                else
                {
                    // Do not encode the character
                    str.push_back(c);
                }
            }

            return str;
        }

        // Decode a string
        static std::string decode(const std::string& src, const char d = '\\')
        {
            // Get the length of the given string 
            const std::size_t len = src.length();

            // Check the length
            if (len == 0)
            {
                // The given string is empty
                return src;
            }

            // Search for slashes ('\')
            std::size_t pos = src.find_first_of(d);

            // Check that slashes are found
            if (pos == std::string::npos)
            {
                // The given string doesn't contain encoded characters
                return src;
            }

            // The number of characters after the slash in the code
            const std::size_t step = 3;

            // Some useful variables
            std::size_t start = 0;
            std::size_t end = 0;

            // The result string
            std::string str{ "" };

            // Decode the string
            do
            {
                // Update 'end' position
                end = pos + 1;

                // Calculate delta between current and start positions
                std::size_t delta = (end - start);

                // Handle the string before the slash
                if (delta > 1) 
                {
                    // We have characters before the slash
                    str.append( src.substr( start, (delta - 1) ) ); 
                    start += delta;
                }
                else 
                {
                    // We haven't characters before the slash
                    start++;
                }

                // Calculate delta between the end of the string and current positions
                delta = (len - end);

                // Check that we have at least 3 characters after the slash
                if (delta >= step)
                {
                    // Get the code
                    std::string code = src.substr(end, step);

                    // The valid code flag
                    bool valid = true;

                    // Checking the code . . . 
                    for (char const& c : code)
                    {
                        if (std::isdigit(c) == 0)
                        {
                            // Non valid code
                            valid = false;

                            // Remove the slash
                            if (c == d)
                            {
                                start--;
                                code.pop_back();
                            }

                            break;
                        }
                    }

                    // Check the flag
                    if (valid == true)
                    {
                        // Convert std::string to unsigned long
                        const unsigned long ascii = std::stoul(code, nullptr, 10);

                        // Check the code number
                        if ( (ascii >= 192 && ascii <= 255) || (ascii == 168) || (ascii == 184) ) // From 'А' to 'я'
                        {
                            // Valid code
                            str.push_back(static_cast<const char>(ascii));
                        }
                        else
                        {
                            // Non-valid code
                            code.insert(code.begin(), d); str.append(code);
                        }
                    }
                    else
                    {
                        // Non-valid code
                        code.insert(code.begin(), d); str.append(code);
                    }

                    // Update 'start' position
                    start += step;
                }
                else
                {
                    // Append the rest of the string
                    std::string sub = src.substr(end, delta);
                    sub.insert(sub.begin(), d); str.append(sub);

                    // Update 'start' position
                    start += delta;
                }
            } 
            while ( (pos = src.find(d, start) ) != std::string::npos );

            // Handle the rest of string
            if (start != len)
            {
                str.append(src.substr(start, (len - start)));
            }

            return str;
        }
};

// The entry point
int main(int argc, char* argv[])
{
    // For Russian language support
    setlocale(LC_ALL, "ru");


    // Tests for Coder::encode()
    std::cout << "Coder::encode() test:" << std::endl;
    {
        // Empty string
        std::cout << Coder::encode("") << std::endl;

        // Russian alphabet
        std::cout << Coder::encode("абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ") << std::endl;

        // Hello world!
        std::cout << Coder::encode("Привет, мир!") << std::endl;

        // 'Ё' and 'ё'
        std::cout << Coder::encode("Ё and ё!") << std::endl;
    }

    // Tests for Coder::decode()
    std::cout << std::endl << std::endl << "Coder::decode() test:" << std::endl;
    {
        // Empty string
        std::cout << Coder::decode("") << std::endl;

        // Non-encoded string
        std::cout << Coder::decode("Hello world!") << std::endl;

        // Encoded string
        std::cout << Coder::decode("\\207\\240\\232\\226\\229\\242 \\236\\232\\240") << std::endl;

        // Encoded string with non-encoded characters (1)
        std::cout << Coder::decode("\\207\\240\\232\\226\\229\\242 \\236\\232\\240!!") << std::endl;

        // Encoded string with non-encoded characters (2)
        std::cout << Coder::decode("Hello world is: \\207\\240\\232\\226\\229\\242 \\236\\232\\240!") << std::endl;
        
        // Encoded string with non-encoded characters (3)
        std::cout << Coder::decode("AAAA\\207\\240BBB\\232\\226CCC\\229\\242 \\236DDD\\232\\240FFF") << std::endl;

        // Encoded string with non-encoded characters and non-valid code \600, \100 and \333
        std::cout << Coder::decode("Hello world is: \\207\\240\\600\\226\\229\\242 \\100\\232\\240!\\333") << std::endl;

        // Encoded string with non-encoded characters and non-valid code \AAA, \bbb and \CcC
        std::cout << Coder::decode("Hello world is: \\207\\240\\AAA\\226\\229\\242 \\bbb\\232\\240!\\CcC") << std::endl;

        // Encoded string with non-encoded characters and non-valid code \24, \19 and \32
        std::cout << Coder::decode("Hello world is: \\207\\240\\24\\226\\229\\242 \\19\\232\\240!\\32") << std::endl;

        // Russian alphabet
        std::cout << Coder::decode("\\224\\225\\226\\227\\228\\229\\184\\230\\231\\232\\233\\234\\235\\236\\237\\238\\239\\240\\241\\242\\243\\244\\245\\246\\247\\248\\249\\250\\251\\252\\253\\254\\255\\192\\193\\194\\195\\196\\197\\168\\198\\199\\200\\201\\202\\203\\204\\205\\206\\207\\208\\209\\210\\211\\212\\213\\214\\215\\216\\217\\218\\219\\220\\221\\222\\223");
    }

    return 0;
}

 

Результаты тестов:

Coder::encode() test:

\224\225\226\227\228\229\184\230\231\232\233\234\235\236\237\238\239\240\241\242\243\244\245\246\247\248\249\250\251\252\253\254\255\192\193\194\195\196\197\168\198\199\200\201\202\203\204\205\206\207\208\209\210\211\212\213\214\215\216\217\218\219\220\221\222\223
\207\240\232\226\229\242, \236\232\240!
\168 and \184!


Coder::decode() test:

Hello world!
Привет мир
Привет мир!!
Hello world is: Привет мир!
AAAAПрBBBивCCCет мDDDирFFF
Hello world is: Пр\600вет \100ир!\333
Hello world is: Пр\AAAвет \bbbир!\CcC
Hello world is: Пр\24вет \19ир!\32
абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ

 

 

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...