0 / 0 / 0
Регистрация: 07.11.2012
Сообщений: 10
1
.NET 3.x

Подсчет контрольной суммы файла по CRC32: разобрать код

08.11.2012, 00:49. Показов 15042. Ответов 5
Метки нет (Все метки)

Здравствуйте. Есть вот этот код, суть его в том, что вбивается название файла, подсчитывается восьмизначная шестнадцатеричная контрольная сумма по CRC32 и осуществляется поиск аналогичных файлов во вложенной папке search, ну и выводится на экран что найдено. Так вот, задача не моя. Я очень прошу вас написать подробный комментарий к каждой строчке, чтоб я могла понять код от и до. Всем заранее спасибо!

Написано в C# 2008 под .NET 3.5, на 4 может не взлететь!


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
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.IO;
 
namespace Crypto
{
    class Program
    {
        static uint[] crc_table = new uint[256];
        static string searchDir = "search";
 
        static void BuildTable()
        {
            uint crc;
 
            for (uint i = 0; i < 256; i++)
            {
                crc = i;
                for (int j = 0; j < 8; j++)
                    crc = ((crc & 1) == 1) ? (crc >> 1) ^ 0xEDB88320 : crc >> 1;
 
                crc_table[i] = crc;
            }
        }
 
        static uint Crc32(byte[] array)
        {
            uint result = 0xFFFFFFFF;
 
            for (int i = 0; i < array.Length; i++)
            {
                byte last_byte = (byte)(result & 0xFF);
                result >>= 8;
                result = result ^ crc_table[last_byte ^ array[i]];
            }
 
            return result;
        }
 
        static uint GetFileCrc(string filename)
        {
            var fileInfo = new FileInfo(filename);
            var reader = fileInfo.OpenRead();
            var buffer = new byte[reader.Length];
 
            reader.Read(buffer, 0, (int)reader.Length);
 
            return Crc32(buffer);
        }
 
        static void Main(string[] args)
        {
            BuildTable();
 
            Console.WriteLine("Введите название файла:");
            string filename = Console.ReadLine();
 
            if (!File.Exists(filename))
            {
                Console.WriteLine("Файл {0} не найден!", filename);
                Console.ReadLine();
                return;
            }
 
            uint filecrc = GetFileCrc(filename);
            Console.WriteLine("Контрольная сумма: {0:X}", filecrc);
 
            if (!Directory.Exists("search"))
            {
                Console.WriteLine("Директория {0} не существует!", searchDir);
                Console.ReadLine();
                return;
            }
 
            bool found = false;
 
            var files = new DirectoryInfo(searchDir).GetFiles("*", SearchOption.AllDirectories);
            foreach (var file in files)
            {
                if (GetFileCrc(file.FullName) == filecrc)
                {
                    Console.WriteLine("Файл найден: {0}", file.FullName);
                    found = true;
                }
            }
 
            if (!found)
            {
                Console.WriteLine("Ничего не найдено!");
            }
            Console.ReadLine();
        }
    }
}
Добавлено через 3 часа 26 минут
Помогите, прошу!
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.11.2012, 00:49
Ответы с готовыми решениями:

Передача данных по COM-порту. Подсчет контрольной суммы
Здравствуйте! помогите перевести с языка ПАСКАЛЬ на C# Способ подсчета контрольной суммы. 1. ...

Код по алгоритму. Расчет контрольной суммы
Помогите написать код по этому алгоритму. 1) Пользователь может выбрать ввод 8-ми или на...

Расчет контрольной суммы файла
Доброго времени, форумчане. Подскажите, пожалуйста, примеры расчета контрольной суммы файла....

Как убрать небезопасный код из функции подсчёта контрольной суммы?
Есть функция, представленная производителем приборов для проверки правильности приёма-передачи...

5
606 / 581 / 157
Регистрация: 29.06.2010
Сообщений: 1,620
08.11.2012, 10:23 2
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
        static uint GetFileCrc(string filename)
        {
            var fileInfo = new FileInfo(filename);     //создается "ссылка" на файл
            var reader = fileInfo.OpenRead();          //создаётся поток(Stream) для чтения из файла
            var buffer = new byte[reader.Length];      //создаётся буффер для чтения
 
            reader.Read(buffer, 0, (int)reader.Length);//заполняется буффер
 
            return Crc32(buffer);                      //возвращается CRC
        }
 
        static void Main(string[] args)
        {
            BuildTable();//инициализация таблицы CRC
 
            Console.WriteLine("Введите название файла:");
            string filename = Console.ReadLine(); //получение из консоли имени файла
 
 
            if (!File.Exists(filename)) //если файл не существует
            {
                Console.WriteLine("Файл {0} не найден!", filename);
                Console.ReadLine();
                return; //выход
            }
 
            uint filecrc = GetFileCrc(filename);//вызов метода расчета контрольной суммы
            Console.WriteLine("Контрольная сумма: {0:X}", filecrc);
 
            if (!Directory.Exists("search")) //если рядом с exe файлом нет папки "Search"..
            {                                //хотя это не совсем корректно. если запустить файл из коммандной строки строчкой вида:
                                             //C:\Windows>D:\Test\Test.exe - то поиск папки будет происходить в C:\Windows\, хотя файл в D:\Test\
                
                Console.WriteLine("Директория {0} не существует!", searchDir);
                Console.ReadLine();
                return; //выход
            }
 
            bool found = false; //флаг того, что существуют такиеже файлы. первоначально ложь
 
            var files = new DirectoryInfo(searchDir).GetFiles("*", SearchOption.AllDirectories);//поиск в каталоге Search и во всех подкаталогах всех файлов
            foreach (var file in files) //для каждого из найденных файлов..
            {
                if (GetFileCrc(file.FullName) == filecrc) //если контрольная сумма совпадает
                {
                    Console.WriteLine("Файл найден: {0}", file.FullName); //выдача имени файла
                    found = true; //установка флага того что найденно что-либо в истину
                }
            }
 
            if (!found) //если флаг всё ещё ложь
            {
                Console.WriteLine("Ничего не найдено!"); //сообщение об этом
            }
            Console.ReadLine();
        
        }//выход
    }
}
а сам CRC - это отдельная тема, можешь почитать:
http://ru.wikipedia.org/wiki/%... 0%BE%D0%B4
3
0 / 0 / 0
Регистрация: 07.11.2012
Сообщений: 10
08.11.2012, 13:55  [ТС] 3
Special-Owl, да уж читала, спасибо. =)

Не могли бы вы ещё вот этот кусок объяснить? Тут сравнение с таблицей же идёт? И что значит array.Length?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
static uint Crc32(byte[] array)
        {
            uint result = 0xFFFFFFFF;
 
            for (int i = 0; i < array.Length; i++)
            {
                byte last_byte = (byte)(result & 0xFF);
                result >>= 8;
                result = result ^ crc_table[last_byte ^ array[i]];
            }
 
            return result;
        }
0
606 / 581 / 157
Регистрация: 29.06.2010
Сообщений: 1,620
08.11.2012, 14:27 4
Цитата Сообщение от Lana_Mayer Посмотреть сообщение
array.Length
это количество байт в массиве для которого и производится расчет.

если по порядку, то лучше всего сразу перейти в двоичный код:

1)объявляем переменную 111111111111111111111111111 (32 еденицы, 0xFFFFFFFF)

--------------------------------------------------------------------------------------
2)для каждого байта в принятом массиве...

2.1)выбираем последний(более грамотное слово это младший или старший, но я забыл где какое) байт объявленной переменной (last_byte = (byte)(result & 0xFF)) (маскируем единицами, но на самом деле это не нужно, лишнее)

2.2)сдвигаем объявленный массив вправо на 1 байт (8 бит (единиц)), т.е. было, допустим, 32 единицы, стало 8 нулей и 24 единицы.

2.3) применяем операцию исключающее ИЛИ к объявленной переменной (в первый раз к 000000001111111111111111111111 11) с заполненным ранее массивом.

2.3.1) номер эллемента массива получается путем применения операции исключающее ИЛИ последнего байта объявленной переменной и текущего эллемента принятого массива.

2.3.2) операция ИЛИ - это побитовое сравнение возвращающее истину если эллементы НЕ равны, т.е.
0^0=0
1^1=0
1^0=1
0^1=1
ну и соответственно 1010^1100=0110

-----------------------------------------это всё в цикле, шаг два--------------

3) возвращаем модернизированную объявленную переменную

нюансы:
crc_table объявленн как массив на 254 эллемента, потомучто результат операции исключающее ИЛИ, проведённое над двумя байтами, будет занимать 1 байт. т.е. максимум 11111111 что равно 255 (ну и индекс начинается с нуля)

Добавлено через 2 минуты
пытался объяснить кратко, получилось не очень понятно. по этому и давал ссылку на википедию.
P.S. пункт 2.3.2 - это комментарий к тому как получается результат операций в пунктах 2.3 и 2.3.1
2
0 / 0 / 0
Регистрация: 07.11.2012
Сообщений: 10
08.11.2012, 21:42  [ТС] 5
А
C#
1
result >>= 8;
это что за значок вообще? В первый раз такой вижу.
0
606 / 581 / 157
Регистрация: 29.06.2010
Сообщений: 1,620
09.11.2012, 09:42 6
Объясните принцип работы операторов
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.11.2012, 09:42
Помогаю со студенческими работами здесь

Функция подсчета контрольной суммы файла и занятый файл
Есть функция: private string MD5Checksumm(string path) { using (FileStream...

Вычисление контрольной суммы CRC32
Столкнулся с проблемой... Есть процедурка вычисления crc32. Модули использовать не хочу, есть...

Подсчет контрольной суммы файла
Подсчет контрольной суммы файла (суммы байт по модулю 256). Нить считывает участок файла и считает...

Подсчет контрольной суммы файла на ASP.
Приветствуйю... ТАкая проблема возникла... Один сервер с другого скачивает файл. Нужно убедиться...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru