Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
1267 / 968 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
1

Разбор Bencoding (.torrent)

03.05.2010, 22:09. Показов 2082. Ответов 7

пытаюсь значит сделать читалку .torrent файлов , нашел спецификацию тут (или тут на русском)
разобрался вроде, пытаюсь читать с сохранением оргинальной структуры для начала(т.е если там словарь-списков-словарей то и я читаю его в том же виде), судя по отладчику все работает

вобщем проблема - поле pieces содержит
string consisting of the concatenation of all 20-byte SHA1 hash values, one per piece (byte string, i.e. not urlencoded)
строка из объединённых 20-байтных SHA1 хэшей кусков.
на практике это выглядит как
pieces140:�S�]m]�6�|��[��&n��1�Ӧ��YR����ʮ|�y�~Ɉf@թ���oج-b�:%.V�Q;/��'^�´ʐӿX]c�L�ႅ�U@�iˎ��d��@������;��H>�e.VUϩܕaޝ�
сама проблема в том, что длина строки не совпадает, т.е вместо заявленных 140 символов эти крокозябры занимают скажем 127

все строки в этом Bencoding лежат в виде <длина строки>:<сама строка>, например
6:myName --- это строка myName

может кто сталкивался - че делать? не читать дальше? там ведь окончания словарей и еще немного информации полезной в конце...
может быть проблема в том, что я сначала считываю весь файл в строку, а потом уже раскладываю по полочкам?

вот основа кода, хотя врядли с кода тут будет толк
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//весь файл это словарь
Dictionary<string, object> dict = new Dictionary<string, object>();
string line; //сама строка со всеми данными
 int index ; //для прохода по строке
 
 
 
 
//в обработчике некой кнопки
index = 1; //вначале всегда d т.е начало словаря, его проще пропустить
 while (index < line.Length)
            {
                dict.Add(ReadString(), ReadFile());
            }
 
//сами методы чтения
        private object ReadFile()
        {
            object someObject = new object();
            switch (line[index])
            {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    someObject = ReadString();
                    break;
                case 'i':
                    ++index;
                    someObject = ReadInteger();
                    ++index;
                    break;
                case 'l':
                    ++index;
                    someObject = ReadList();
                    ++index;
                    break;
                case 'd':
                    ++index;
                    someObject = ReadDictionary();
                    ++index;
                    break;
                default:
                    ++index;
                    break;
            }
            return someObject;
        }
        private object ReadDictionary()
        {
            Dictionary<string, object> tempDict = new Dictionary<string, object>();
 
            while (line[index] != 'e')
                tempDict.Add(ReadString(), ReadFile());
 
            return tempDict;
        }
        private object ReadList()
        {
            List<object> list = new List<object>();
 
            while (line[index] != 'e')
                list.Add(ReadFile());
 
            return list;
        }
        private string ReadInteger()
        {
            string temp = "";
            while (line[index] != 'e')
            {
                temp += line[index];
                ++index;
            }
            return temp;
        }
        private string ReadString()
        {
            string temp = "";
 
            while (line[index] != ':')
            {
                temp += line[index];
                ++index;
            }
 
            int lenght = Int32.Parse(temp);
            temp = line.Substring(++index, lenght);
            index += lenght;
 
            //if (previousString == "pieces")
            //{
            //    return "error!!!";
            //    ++index;
            //}
            //previousString = temp;
            return temp;
        }
        //string previousString = "";





Добавлено через 4 часа 3 минуты
пока сделал затычку, просто пропускаю этот кусок
работоспособность кода около 90% (из 1133 файлов без ошибок читает 964)

одна из главных проблем в русских символах
опять тоже самое - длина не соответствует вообще ниразу
37:2-ой сезон-26 эпизодов
тут 22 символа, а заявлено что 37 - где логика?

вопрос:
каким образом в строке "2-ой сезон-26 эпизодов" можно насчитать 37 символов?
т.е может кодировка какая-то особенная или что?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.05.2010, 22:09
Ответы с готовыми решениями:

Как именно задается размер строк в Bencoding?
Пишу разборщик торрент-файла на C#. Столкнулся с проблемой. Нигде не нашел в стандарте Bencoding в...

Книга "Конечный автомат 2: Возвращение". Часть 1. Разбор. Глава 8. Имя, проверка строки и разбор до. На том ли я пути?
Наверное, иногда прилюдно выругаться полезно... Стоило мне в предыдущей теме написать...

Torrent
Привет усем!! Есть такой трабл как торрент! Когда он включон (активны или пасивны скачки не имеет...

u Torrent
Прошу помочь!!!Тема давно битая ,а я все избавиться не могу от синего экрана перезагрузки.У меня...

7
мну довольно <(-__-)l
214 / 203 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
03.05.2010, 22:20 2
помочь не могу...
но впервые вижу человека который использует
C#
1
2
3
++index; 
//вместо 
index++;
0
1267 / 968 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
03.05.2010, 22:24  [ТС] 3
такой вид инкремента теоретически работает быстрей, давно читал где-то

вроде как в постфиксной(i++) форме создается дополнительная переменная для хранения предыдущего значения и еще что-то, короче на 1-2 операции больше (на уровне ассемблера конечно)
0
Эксперт С++
2335 / 1708 / 148
Регистрация: 06.03.2009
Сообщений: 3,675
03.05.2010, 22:28 4
Цитата Сообщение от m0nax Посмотреть сообщение
такой вид инкремента теоретически работает быстрей, давно читал где-то
Для встроенных типов разницы никакой.
0
мну довольно <(-__-)l
214 / 203 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
03.05.2010, 22:32 5
да я знаю про это. однако мне и в голову не приходило экономить доли миллисекунды=)
0
1267 / 968 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
04.05.2010, 00:11  [ТС] 6
Лучший ответ Сообщение было отмечено OwenGlendower как решение

Решение

вобщем все проблемы исчезли после явного указания кодировки для StreamReader, работоспособность 100%, вопросов больше нет )
C#
1
StreamReader sr = new StreamReader(path, Encoding.Default)
gGrn-7DA оно же не мешает, пусть экономятся эти микросекунды ) тем более .NEt излишней скоростью не страдает...
0
мну довольно <(-__-)l
214 / 203 / 15
Регистрация: 17.01.2010
Сообщений: 2,462
04.05.2010, 06:32 7
ты с чем сравниваешь? с джава или ассемьлером? у языков свои особенности...и что что а скорости хватает=)
0
1267 / 968 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
04.05.2010, 22:39  [ТС] 8
вобщем вот чего получилось в итоге
если кто потом найдет тему в поиске или гугле (на NET не встречал ничего похожего в инете )
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
 class TorrentReader
    {
        object someObject = new object();
        byte[] buffer;
        char currentChar;
        int index;
        string temp;
 
        private Dictionary<string, object> dict;
        public Dictionary<string, object> Dict
        {
            get
            {
                if (dict != null)
                    return dict;
                else
                {
                    throw new NullReferenceException();
                }
            }
        }
        public void Read(string path)
        {
            index = 0;
 
            using (FileStream fs = new FileStream(path, FileMode.Open))
            {
                buffer = new byte[fs.Length];
                fs.Read(buffer, 0, buffer.Length);
            }
 
            dict = ReadFile() as Dictionary<string, object>;
 
            if (dict == null)
                throw new Exception("Структура файла не соответствует .torrent файлам");
        }
 
        private object ReadFile()
        {
            switch (Convert.ToChar(buffer[index]))
            {
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    someObject = ReadString();
                    break;
                case 'i':
                    someObject = ReadInteger();
                    break;
                case 'l':
                    someObject = ReadList();
                    break;
                case 'd':
                    someObject = ReadDictionary();
                    break;
            }
            return someObject;
        }
 
        private object ReadDictionary()
        {
            Dictionary<string, object> tempDict = new Dictionary<string, object>();
            ++index;
 
            while (Convert.ToChar(buffer[index]) != 'e')
                tempDict.Add(ReadString(), ReadFile());
 
            ++index;
            return tempDict;
        }
 
        private object ReadList()
        {
            List<object> list = new List<object>();
            ++index;
 
            while (Convert.ToChar(buffer[index]) != 'e')
                list.Add(ReadFile());
 
            ++index;
            return list;
        }
 
        private UInt64 ReadInteger()
        {
            temp = "";
            while ((currentChar = Convert.ToChar(buffer[++index])) != 'e')
                temp += currentChar;
 
            ++index;
 
            return UInt64.Parse(temp);
        }
 
        private string ReadString()
        {
            temp = "";
            while ((currentChar = Convert.ToChar(buffer[index++])) != ':')
                temp += currentChar;
 
            int lenght = Int32.Parse(temp);
 
            temp = Encoding.UTF8.GetString(buffer, index, lenght);
 
            if (temp.Contains(char.ConvertFromUtf32(65533)))
            {
                temp = Encoding.GetEncoding(1251).GetString(buffer, index, lenght);
            }
 
 
            index += lenght;
            return temp;
        }
    }
в результате имеется словарь со всеми данными из файла с той же замороченой структурой
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.05.2010, 22:39

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Torrent
Почему не могу скачать файлы с торрента, загрузка вообще идет. Раньше любые файлы свободно скачал,...

torrent 2.0.3
Доброго времени суток уважаемые форумчане!у меня стояло на закачке 16 трекеров.11 готовых и 5...

Torrent
дядя говорит что есть торрент, с помощью которого можно подключиться к тюнеру Dreambox по LAN..И...

torrent
Хочу скачать себе торент но сервер ко мне не пускает .exe файлы, может ктонить может сбросить мне...


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

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

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