Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
44 / 18 / 5
Регистрация: 29.12.2015
Сообщений: 1,714
1

Парсинг hex значений

29.06.2018, 05:47. Показов 2036. Ответов 62
Метки нет (Все метки)

Здравствуйте. В ASM файле есть такая строка к примеру
dc.w 0, $8CE, $6AC, $48A, $268, $46, $224, 2 ; earth

Я помещаю это в виде строкового массива
$8CE
$6AC
$48A
$268
$46
$224
2

Короче это цвета. Например 8CE это своеобразная шестнадцетеричная BGR палитра если перевести в RGB то приблизительно будет

255, 219, 146

Так вот в некоторых местах Есть $46 к примеру что будет как $046

Перевод в rgb палитру делается по формуле

r = b * 255 / 14
g = g * 255 / 14
b = r * 255 / 14

Так вот вот в этой своеобразной палитре если цвет начинается на 0 то его не пишут. Только если заканчивается

Как мне сделать парсинг палитры чтобы получить дополнительные 0

Добавлено через 48 минут
В принципе и самому дошло как
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string GetSEGAColor(string s)
        {
            s = s.Replace("$", "");
 
            var ret = "";
            switch (s.Length)
            {
                case 1:  ret = "00" + s; break;
                case 2:  ret = "0"  + s; break;
                case 3:  ret =        s; break;
                default: ret =      "0"; break;
            }
 
            return ret;
        }
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.06.2018, 05:47
Ответы с готовыми решениями:

Парсинг большого количества hex значений из текстового файла
Нужно из текстового файла прочитать кучу hex целочисленных значений от int16 до uint64, а книжку...

Парсинг XML значений для получения значений Double
Всем добрый день. Есть XML файл в котором нужно спарсить значения double. Подскажите пожалуйста...

Замена hex значений
Читаю файл вот так: procedure ReadFileAsHex(const AFileName: string; ADestination: TStrings); var...

Редактирование hex значений в файле
Всем привет. Не знаю как сделать то что на 2 скриншотах. На 1 до, на втором - после. В какую...

__________________

Записывайтесь на профессиональные курсы С#-разработчиков‌
62
210 / 114 / 17
Регистрация: 01.06.2018
Сообщений: 1,749
29.06.2018, 19:35 2
Захотелось написать свой вариант
C#
1
2
3
4
5
6
        string GetSEGAColor(string s)
        {
            s = s.Substring(1);
            if (s.Length < 4) while (s.Length < 3) s = String.Concat("0", s);
            return s;
        }
Добавлено через 10 минут
может кто-то красиво сможет заменить while?

Добавлено через 12 минут
Цитата Сообщение от belalugoci Посмотреть сообщение
Захотелось написать свой вариант
там неправильно и сложно , переделал
C#
1
2
3
4
5
6
        string GetSEGAColor(string s)
        {
            s = s.Substring(1);
            while (s.Length < 3) s = String.Concat("0", s);
            return s;
        }
Добавлено через 8 часов 44 минуты
Еще придумал, никто через регулярные выражения не напишет?
C#
1
2
3
4
        string GetSEGAColor(string s)
        {
            return String.Concat("000".Substring(s.Length - 2), s.Substring(1)).Substring(1);
        }
Добавлено через 9 минут
наверное имеет смысл делать реализацию таким образом чтобы в памяти как можно меньшее число раз создавались копии строк.

Добавлено через 52 минуты
И ещё:
C#
1
return String.Format("{0,2:X3}", Convert.ToInt32(String.Concat("0x", s.Substring(1)), 16));
Добавлено через 14 минут
Больше кода Богу кода:
C#
1
return Convert.ToInt32(String.Concat("0x", s.Substring(1)), 16).ToString("X3");
0
Модератор
Эксперт .NET
5304 / 4100 / 1183
Регистрация: 12.10.2013
Сообщений: 11,909
Записей в блоге: 2
29.06.2018, 21:51 3
Цитата Сообщение от belalugoci Посмотреть сообщение
Больше кода Богу кода:
Больше, еще больше.
Задачу не совсем понял, но вот велосипед. Использовал такой файл:
dc.w 0, $8CE, $6AC, $48A, $268, $46, $224, 2 ; earth
dc.w 0, $8CE, $6AC, $48A, $268, $46, $224, 2 ; earth
dc.w 0, $8CE, $6AC, $48A, $268, $46, $224, 2 ; earth
dc.w 0, $8CE, $6AC, $48A, $268, $46, $224, 2 ; earth
dc.w 0, $8CE, $6AC, $48A, $268, $46, $224, 2 ; earth
dc.w 0, $8CE, $6AC, $48A, $268, $46, $224, 2 ; earth
dc.w 0, $8CE, $6AC, $48A, $268, $46, $224, 2 ; earth
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Globalization;
 
namespace ConsoleApp1 {
    class Program {
        static void Main(string[] args) {
            string path = "test.txt";
            List<ColorObject> colorList = new List<ColorObject>();
            using (StreamReader sr = new StreamReader(File.OpenRead(path))) {
                string line = null;
                while (!string.IsNullOrWhiteSpace(line=sr.ReadLine())) {
                    int[] colorParams = line.Split(new[] { ' ', '.', ',' }, StringSplitOptions.RemoveEmptyEntries).
                        Where(b => b.StartsWith("$")).
                        Select(m => m.Replace("$", "0x")).
                        Select(n => Convert.ToInt32(n, 16)).
                        Select(v => {
                            int h = v < 0x100 ? v * 0x100 : v;
                            return h;
                        }).ToArray();
                    if (colorParams.Count() != 6) {
                        continue;
                    }
                    colorList.AddRange(new[]{
                        new ColorObject {
                            R=colorParams[0],
                            G=colorParams[1],
                            B=colorParams[2]
                        },
                        new ColorObject {
                            R=colorParams[3],
                            G=colorParams[4],
                            B=colorParams[5]
                        } });
                }
            }
        }
    }
    public class ColorObject {
        int r;
        int g;
        int b;
        public int R {
            get {
                return r; }
            set {
                r = GetRealValue(value);
            }
        }
        public int G {
            get {
                return g;
            }
            set {
                g = GetRealValue(value);
            }
        }
        public int B {
            get {
                return b;
            }
            set {
                b = GetRealValue(value);
            }
        }
        private int GetRealValue(int value) {
            return value * 255 / 14;
        }
    }
}
0
44 / 18 / 5
Регистрация: 29.12.2015
Сообщений: 1,714
03.07.2018, 23:57  [ТС] 4
Цитата Сообщение от insite2012 Посмотреть сообщение
Больше, еще больше.
Задачу не совсем понял, но вот велосипед. Использовал такой файл:
$ символа может и не быть
В принципе вот так работает нормально
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
string GetSEGAColor(string s)
        {
            s = s.Replace("$", "");
 
            while (s.Length < 3) s = String.Concat("0", s);
 
            return s;
        }
 
        Color SEGAColorToColor(string s)
        {
            var sb = s.Substring(0, 1);
            var sg = s.Substring(1, 1);
            var sr = s.Substring(2, 1);
 
            var hb = Convert.ToInt16(sb, 16);
            var hg = Convert.ToInt16(sg, 16);
            var hr = Convert.ToInt16(sr, 16);
 
            var b = (int)(hb * 255 / 14);
            var g = (int)(hg * 255 / 14);
            var r = (int)(hr * 255 / 14);
 
            return Color.FromArgb(r, g, b);
        }
1 метод получает код цвета в формате Сеги второй метод переводит палитру из формата Сеги в формат c#

1 метод по сути из строки таблицы в ASM файле сегавской игры переводит в нормальный вид палитры Sega
0
Эксперт .NET
8861 / 6172 / 1029
Регистрация: 21.01.2016
Сообщений: 23,326
04.07.2018, 04:09 5
Я могу понять наличие кучи методов Replace, Concat и Substring, когда нужно действительно получить именно строку (для сохранения, к примеру). Но так гадить в память только, чтобы можно было вызвать ToInt16...
0
44 / 18 / 5
Регистрация: 29.12.2015
Сообщений: 1,714
04.07.2018, 04:22  [ТС] 6
Цитата Сообщение от Usaga Посмотреть сообщение
Я могу понять наличие кучи методов Replace, Concat и Substring, когда нужно действительно получить именно строку (для сохранения, к примеру). Но так гадить в память только, чтобы можно было вызвать ToInt16...
Ага может ты знаешь другой способ. Как уже сказал $ может и не быть. Тем более что значений может быть не 3 а меньше 3х например нули если они идут перед можно и не указывать. А $ ставиться лишь для того чтобы подвердить что данная строка является шестнадцетеричным числом а не строкой. Например если там тупо от от 0 до 8 и только 1 например так
0 2 4 6 8
То перед ними $ может и не стоять хотя поставив его ничего не изменится но не я выковыривл из игры файлы я лишь делаю возможность их редактирования через графический интерфейс так что приходится придержиаться формата файлов и как они устроены
Ну скину вам к примеру вот такую вот таблицу.

Assembler
1
2
3
4
5
6
7
palette_region:
 dc.w     0, $8CE, $6AC, $48A, $268,  $46, $224,    2   
 dc.w     0,   $C,   $A,    8,    6,    4,    2,    0   
 dc.w     0, $E40, $C40, $A40, $840, $620, $420, $200   
 dc.w     0,  $C0,  $A0,  $80,  $60,  $40,  $20,    0   ; ordos
 dc.w     0, $E0E, $C0C, $A0A, $808, $606, $404, $202   
 dc.w     0, $EEE, $CCC, $AAA, $888, $666, $444, $222
Врядле кто поймет что тут а это данные палитра регионов карты из сегавской игры
0
Эксперт .NET
8861 / 6172 / 1029
Регистрация: 21.01.2016
Сообщений: 23,326
04.07.2018, 04:34 7
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Ага может ты знаешь другой способ.
Да, парсить строку вручную с помощью обычного конечного автомата, который проигнорирует лишние символы без всяких Replace. И число считывать целиком, а уже потом из него выбирать восьмибитные компоненты и преобразовывать в нужный формат.

На всё провсё ни одного Replace, Concat и Substring. Вы же, надеюсь, понимаете, что Convert.ToInt16 не каким-то волшебным образом 0x0C в 12 переводит?
0
210 / 114 / 17
Регистрация: 01.06.2018
Сообщений: 1,749
04.07.2018, 04:42 8
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Врядле кто поймет что тут а это данные палитра регионов карты из сегавской игры
достаточно понимать что это массив данных. Usaga о том, что задача добавления ведущих нулей в строку плавно перетекла в банальный ToInt16, что делает операцию со строкой глупой.
Например мой код:
C#
1
return Convert.ToInt32(String.Concat("0x", s.Substring(1)), 16).ToString("X3");
Вполне можно использовать как
C#
1
return Convert.ToInt16(String.Concat("0x", s.Substring(1)), 16);
Ведь вам даже не нужно 16-ое значение как и строка.

Добавлено через 2 минуты
Цитата Сообщение от Usaga Посмотреть сообщение
На всё провсё ни одного Replace, Concat и Substring.
имхо, но я считаю что если в куске кода нет требований к производительности, то его лучше делать с минимальным набором кода.
0
Эксперт .NET
8861 / 6172 / 1029
Регистрация: 21.01.2016
Сообщений: 23,326
04.07.2018, 05:33 9
belalugoci, тут явно не ставилась цель минимизировать объём кода или сделать как можно проще (чтобы не греть голову). Видно, что задача решалась интуицией и методом тыка.

Я имел в виду две вещи:
* Строка - массив символов, её можно вручную разбирать, перебирать символы вдоль и поперёк.
* Перевод шестнадцатиричного строкового значения в бинарное - операция не секретная и не из ракетостроительной науки. Это чуть ли не первая задача, которую фана ради делают даже на ассемблере.
* Не нужно "добивать" нулями число до нужного количество символов, число останется тем же. Достаточно разом его распарсить, а потом методом сдвига и логического ИЛИ разбить на цветовые компоненты. Метод Color.FromArgb собирает код цвета из компонентов, логично предположить, что возможно и обратное.
0
210 / 114 / 17
Регистрация: 01.06.2018
Сообщений: 1,749
04.07.2018, 05:38 10
Цитата Сообщение от Usaga Посмотреть сообщение
тут явно не ставилась цель минимизировать объём кода
я пока даже не понял самой цели задания (глобальной). Вполне вероятно что решение бы тогда удивило и автора
0
Эксперт .NET
8861 / 6172 / 1029
Регистрация: 21.01.2016
Сообщений: 23,326
04.07.2018, 05:55 11
Я вижу примерно такое решение разбора кода цвета:

Кликните здесь для просмотра всего текста

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.Drawing;
 
namespace Experiments
{
    internal class Program
    {
        static int GetHalfByteFromChar(char c)
        {
            if (c >= '0' && c <= '9')
                return c - '0';
 
            if (c >= 'A' && c <= 'F')
                return c - 'A' + 10;
 
            if (c >= 'a' && c <= 'f')
                return c - 'a' + 10;
 
            throw new Exception("Wrong char code");
        }
 
        static Color FromSEGAColor(string segaColor)
        {
            var colorCode = 0;
 
            foreach (var c in segaColor)
            {
                if (Char.IsDigit(c) || Char.IsLetter(c))
                    colorCode = (colorCode << 8) + GetHalfByteFromChar(c);
            }
 
            var b = ((colorCode & 0xff) * 255) / 14;
            var g = (((colorCode >> 8) & 0xff) * 255) / 14;
            var r = (((colorCode >> 16) & 0xff) * 255) / 14;
 
            return Color.FromArgb(r, g, b);
        }
 
        static void Main()
        {
            var segaColors = new string[] { "$8CE", "$224", "2" };
 
            foreach (var segaColor in segaColors)
            {
                var color = FromSEGAColor(segaColor);
                Console.WriteLine($"{segaColor} -> {color}");
            }
 
            Console.ReadKey();
        }
    }
}


Никаких пересозданий строк. Никакого мусора.

Добавлено через 5 минут
Упс. (colorCode << 8) замените на (colorCode << 4)
0
44 / 18 / 5
Регистрация: 29.12.2015
Сообщений: 1,714
04.07.2018, 05:55  [ТС] 12
Цитата Сообщение от Usaga Посмотреть сообщение
C#
1
2
3
4
5
6
7
8
9
10
static int GetByteFromChar(char c)
        {
            if (c >= '0' && c <= '9')
                return c - '0';
if (c >= 'A' && c <= 'F')
                return c - 'A';
if (c >= 'a' && c <= 'f')
                return c - 'a';
throw new Exception("Wrong char code");
        }
Честно не могу понять зачем это. И еще. GetSEGAColor у меня используется не постоянно а толькопри парсинге. Например если я получаю код цвета через созданную палитру то там это не требуется.
0
Эксперт .NET
8861 / 6172 / 1029
Регистрация: 21.01.2016
Сообщений: 23,326
04.07.2018, 05:57 13
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Честно не могу понять зачем это
Разбор шестнадцатиричного представления числа.
0
44 / 18 / 5
Регистрация: 29.12.2015
Сообщений: 1,714
04.07.2018, 06:02  [ТС] 14
Цитата Сообщение от Usaga Посмотреть сообщение
Разбор шестнадцатиричного представления числа.
Как это зачем. Я чтоли писал игру. Я же не могу в C# работать чисто в палитре SEGA
Там Палитра Color или если проще то ARGB ну или просто RGB
можно в принципе как вариант HTML но тока я не знаю формулы преобразования 16тибитного BGR в HTML палитру
0
210 / 114 / 17
Регистрация: 01.06.2018
Сообщений: 1,749
04.07.2018, 06:04 15
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
GetSEGAColor у меня используется не постоянно а только при парсинге.
так можно сказать про все программы или их части, но это не повод писать велосипед передвигающийся на костылях.
0
44 / 18 / 5
Регистрация: 29.12.2015
Сообщений: 1,714
04.07.2018, 06:18  [ТС] 16
Кстати может еще поможешь переделать этот кусок

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
string ColorToSEGAColor(Color c)
        {
            int r = c.R;
            int g = c.G;
            int b = c.B;
 
            int sega_r = (int)Math.Round(Convert.ToDouble(r) * 7.0 / 255.0) * 2;
 
            int sega_g = (int)Math.Round(Convert.ToDouble(g) * 7.0 / 255.0) * 2;
 
            int sega_b = (int)Math.Round(Convert.ToDouble(b) * 7.0 / 255.0) * 2;
 
            return ((c.B * 7 / 255) * 2).ToString("X") + ((c.G * 7 / 255) * 2).ToString("X") + ((c.R * 7 / 255) * 2).ToString("X");
        }
Добавлено через 1 минуту
Цитата Сообщение от belalugoci Посмотреть сообщение
так можно сказать про все программы или их части, но это не повод писать велосипед передвигающийся на костылях.
Извиняюсь я был не прав. Я не очень силен в математике поэтому и пишу как знаю

Добавлено через 3 минуты
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Кстати может еще поможешь переделать этот кусок
Желательно чтобы сразу убрать нули если они в первых 2х символах но я даже не знаю смогу ли я сохронять изменения ибо внеси изменения не получитя там прийдется с нуля пересоздавать ASM с новыми данными

Жалко что это не бинарник. С бинарником было бы проще. Например тем что просто записал
0
belalugoci
04.07.2018, 06:20
  #17

Не по теме:

Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Извиняюсь я был не прав. Я не очень силен в математике поэтому и пишу как знаю
Если математикой называть умение считать, то я, безусловно, знаю математику.
В остальном здесь на лицо проблема проектирования. Когда реализация программы идет от неправильной парадигмы, то, возможно, результат даже будет достигнут, но как принято говорить - через заднее место.
Кстати большое заблуждение многих, в том числе на этом форуме, что ошибки в реализации связаны исключительно с незнанием C#. На самом деле, как правило, знаний не хватает во многих областях и C# далеко не на первом месте.
Самое главное в жизни - уметь формулировать собственные мысли.

0
44 / 18 / 5
Регистрация: 29.12.2015
Сообщений: 1,714
04.07.2018, 06:23  [ТС] 18
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Кстати может еще поможешь переделать этот кусок
В принцыпе если не создать новых переменных то должно быть так

C#
1
return ((int)Math.Round(((double)c.B * 7 / 255)) * 2).ToString("X") + ((int)Math.Round(((double)c.G * 7 / 255)) * 2).ToString("X") + ((int)Math.Round(((double)c.R * 7 / 255)) * 2).ToString("X");
0
44 / 18 / 5
Регистрация: 29.12.2015
Сообщений: 1,714
04.07.2018, 06:29  [ТС] 19
Парсинг hex значений

Входное значение:
$8CE
0
Эксперт .NET
8861 / 6172 / 1029
Регистрация: 21.01.2016
Сообщений: 23,326
04.07.2018, 06:46 20
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Как это зачем. Я чтоли писал игру. Я же не могу в C# работать чисто в палитре SEGA
Там Палитра Color или если проще то ARGB ну или просто RGB
можно в принципе как вариант HTML но тока я не знаю формулы преобразования 16тибитного BGR в HTML палитру
Я не понял что вы этим всем хотели сказать) Я привёл пример того, как можно более эффективно преобразовать одно в другое, без гор Replace и Substring. Вот и всё.

Добавлено через 3 минуты
Цитата Сообщение от Alexandr_7 Посмотреть сообщение
Входное значение:
$8CE
Всё верно. Я взял за основу ваш код преобразования из палитры "Sega". Вам попался код синего компонента "206", который после преобразования (* 255 / 14) увеличился до неприемлемых 655.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.07.2018, 06:46

Заказываю контрольные, курсовые, дипломные работы и диссертации здесь.

Редактор hex-значений нетипизированного файла через Memo
Хочу написать редактор такого вида: Открываем нетипизированный файл (20 мб) в Memo (или что-то...

Отображение на экране значений головного и хвостового указателей кольцевого буфера в виде hex строк
Отображение на экране значений головного и хвостового указателей кольцевого буфера в виде...

[Dendy] Увеличить начальную скорость падения блоков в tetris.1989 (редактирование значений в HEX редакторе)
Доброго дня! Когда-то мне здесь помогли написать диплом. Теперь снова обращаюсь к Вам. Играю в...

Парсинг значений
Вообщем ситуация такая ( в целом обрисую) Нужно сделать некое подобие трейдера ( чтобы в окне...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.