Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
20 / 20 / 1
Регистрация: 03.09.2014
Сообщений: 35
1

Как ускорить получения crc32 о файле? md5 не читает файлы более 512 мегабайт!

24.02.2016, 08:50. Показов 2296. Ответов 11

Доброго времени суток уважаемые читатели !

столкнулся с очень большой проблемой !

нужно получить от файла некую информацию для апдейтора :
1) размер
2) crc32
3) md5

размер получаю очень быстро

crc32 вообще чудной какой то , проверяю файл весом более 1 гиг , он его парсит минуты 3 , это очень долго , файлов то штук 10
хотя при этом проверяю с помощу утилиты от 7zip , там вообще за 7 секунд отдаёт crc32

а md5 встроенный вообще тупой какой то , если файл больше 512 мегабайт , вообще не получает ничего , выдаёт ошибка чтения

вот код для получения crc32
C#
1
2
3
4
5
6
7
8
void main()
{
     string thisFileCRC32 = FileCRC32.Start(@"C:\setup.bin");
     string thisFileMD5 = FileMD5.Start(@"C:\setup.bin");
 
     Console.WriteLine("crc32 : " + thisFileCRC32);
     Console.WriteLine("md5 : " + thisFileMD5);
}
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System;
using System.Security.Cryptography;
using System.IO;
 
using System.Net;
using System.Windows.Forms;
 
public class FileCRC32 : HashAlgorithm
{
    public const UInt32 DefaultPolynomial = 0xedb88320;
    public const UInt32 DefaultSeed = 0xffffffff;
 
    private UInt32 hash;
    private UInt32 seed;
    private UInt32[] table;
    private static UInt32[] defaultTable;
 
    public static string Start(string FilePath)
    {
        FileCRC32 crc32 = new FileCRC32();
        String result = string.Empty;
        try
        {
            using (FileStream fs = File.OpenRead(FilePath))
            {
                foreach (byte b in crc32.ComputeHash(fs))
                {
                    result += b.ToString("x2").ToLower();
                }
                return result;
            }
        }
        catch { return result; }
    }
 
    public FileCRC32()
    {
        table = InitializeTable(DefaultPolynomial);
        seed = DefaultSeed;
        Initialize();
    }
 
    public FileCRC32(UInt32 polynomial, UInt32 seed)
    {
        table = InitializeTable(polynomial);
        this.seed = seed;
        Initialize();
    }
 
    public override void Initialize()
    {
        hash = seed;
    }
 
    protected override void HashCore(byte[] buffer, int start, int length)
    {
        hash = CalculateHash(table, hash, buffer, start, length);
    }
 
    protected override byte[] HashFinal()
    {
        byte[] hashBuffer = UInt32ToBigEndianBytes(~hash);
        this.HashValue = hashBuffer;
        return hashBuffer;
    }
 
    public override int HashSize
    {
        get { return 32; }
    }
 
    public static UInt32 Compute(byte[] buffer)
    {
        return ~CalculateHash(InitializeTable(DefaultPolynomial), DefaultSeed, buffer, 0, buffer.Length);
    }
 
    public static UInt32 Compute(UInt32 seed, byte[] buffer)
    {
        return ~CalculateHash(InitializeTable(DefaultPolynomial), seed, buffer, 0, buffer.Length);
    }
 
    public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer)
    {
        return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length);
    }
 
    private static UInt32[] InitializeTable(UInt32 polynomial)
    {
        if (polynomial == DefaultPolynomial && defaultTable != null)
            return defaultTable;
 
        UInt32[] createTable = new UInt32[256];
        for (int i = 0; i < 256; i++)
        {
            UInt32 entry = (UInt32)i;
            for (int j = 0; j < 8; j++)
                if ((entry & 1) == 1)
                    entry = (entry >> 1) ^ polynomial;
                else
                    entry = entry >> 1;
            createTable[i] = entry;
        }
 
        if (polynomial == DefaultPolynomial)
            defaultTable = createTable;
 
        return createTable;
    }
 
    private static UInt32 CalculateHash(UInt32[] table, UInt32 seed, byte[] buffer, int start, int size)
    {
        UInt32 crc = seed;
        for (int i = start; i < size; i++)
            unchecked
            {
                crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff];
            }
        return crc;
    }
 
    private byte[] UInt32ToBigEndianBytes(UInt32 x)
    {
        return new byte[] {
   (byte)((x >> 24) & 0xff),
   (byte)((x >> 16) & 0xff),
   (byte)((x >> 8) & 0xff),
   (byte)(x & 0xff)
  };
    }
 
    public string Get(string FilePath)
    {
        FileCRC32 crc32 = new FileCRC32();
        String hash = String.Empty;
 
        using (FileStream fs = File.Open(FilePath, FileMode.Open))
            foreach (byte b in crc32.ComputeHash(fs)) hash += b.ToString("x2").ToLower();
 
        return hash;
    }
}
как оптимизировать что бы быстро получал инфу о файле ?
фрейм ворк 3,5 использую , нужна поддержка WinXP

вот скрипт на md5
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using System.IO;
using System.Security.Cryptography;
 
namespace WebSocketBuilder
{
    class FileMD5
    {
        public static string Start(string path)
        {
            using (FileStream fs = System.IO.File.OpenRead(path))
            {
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] fileData = new byte[fs.Length];
                fs.Read(fileData, 0, (int)fs.Length);
                byte[] checkSum = md5.ComputeHash(fileData);
                string result = BitConverter.ToString(checkSum).Replace("-", String.Empty);
                return result;
            }
        }
    }
}
очень прошу помогите пожалуйста !
md5 думаю откинуть вообще , он не работает с большими файлами
а вот crc32 работает , но очень торможеный !

Может что-то есть по лучше для сравнения файлов для апдейтора ?
0

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

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.02.2016, 08:50
Ответы с готовыми решениями:

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

Ускорить выполнение расчета CRC32
Доброе время суток! Написал кусок кода который считает контрольную сумму папки, проблема в том...

Получить хеш файла (CRC32, MD5, SHA1, TTH, ED2K, BitPrint, AICH....)
Нужно написать приложение выводящее один любой хеш указанного файла, независящий от названия файла....

Как вычисляется CRC32 в exe файле по адресу PE header + 0x8
Работаю под Windows 7 64x + Visual Studio 2010 Если считать в бинарном виде exe-файл в массив и...

11
Rius
24.02.2016, 09:17
  #2

Не по теме:

Один чудной, другой тупой...
Это Вы сам косяки пишете, а не алгоритмы виноваты.

0
483 / 396 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
24.02.2016, 09:30 3
Цитата Сообщение от Rynosce Посмотреть сообщение
md5 думаю откинуть вообще , он не работает с большими файлами
3,5 гига в лёгкую. Файлов больше не нашёл
0
Эксперт .NET
4954 / 3388 / 1422
Регистрация: 09.05.2015
Сообщений: 8,286
24.02.2016, 09:36 4
Лучший ответ Сообщение было отмечено Rynosce как решение

Решение

Все что нужно для MD5, работает с любыми файлами:
OutOfMemory при сравнении MD5 нескольких больших файлов
1
Эксперт .NET
7573 / 5061 / 1204
Регистрация: 25.05.2015
Сообщений: 15,425
Записей в блоге: 14
24.02.2016, 09:41 5
Цитата Сообщение от aquaMakc Посмотреть сообщение
3,5 гига в лёгкую. Файлов больше не нашёл
У вас просто оперативки дофига + винда x64 + AnyCPU/x64. Тут же:
C#
1
2
byte[] fileData = new byte[fs.Length];
fs.Read(fileData, 0, (int)fs.Length);
1
20 / 20 / 1
Регистрация: 03.09.2014
Сообщений: 35
24.02.2016, 10:06  [ТС] 6
Цитата Сообщение от Rius Посмотреть сообщение
Не по теме:
Один чудной, другой тупой...
Это Вы сам косяки пишете, а не алгоритмы виноваты.
Покажите мне где у меня косяки то ?

Цитата Сообщение от aquaMakc Посмотреть сообщение
3,5 гига в лёгкую. Файлов больше не нашёл
Цитата Сообщение от Rius Посмотреть сообщение
У вас просто оперативки дофига + винда x64 + AnyCPU/x64. Тут же:
странно , у меня 8 гиг оперативки , тоже 64 бита

-----------------------------------------------------

Цитата Сообщение от Someone007 Посмотреть сообщение
Все что нужно для MD5, работает с любыми файлами:
OutOfMemory при сравнении MD5 нескольких больших файлов
Спасибо большое !
действительно заработало , теперь файлы по 1 500 гиг спокойно получает !

вот как код реализовал :

C#
1
2
3
4
5
void main()
{
     string thisFileMD5 = FileMD5.Start2(@"C:\setup.bin");
     Console.WriteLine("md5 : " + thisFileMD5);
}
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
using System.IO;
using System.Security.Cryptography;
 
namespace WebSocketBuilder
{
    class FileMD5
    {
        public static string Start(string path)
        {
            using (FileStream fs = System.IO.File.OpenRead(path))
            {
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] fileData = new byte[fs.Length];
                fs.Read(fileData, 0, (int)fs.Length);
                byte[] checkSum = md5.ComputeHash(fileData);
                string result = BitConverter.ToString(checkSum).Replace("-", String.Empty);
                return result;
            }
        }
        public static string Start2(string path)
        {
            using (var md5 = MD5.Create())
            {
                using (var stream = File.OpenRead(path))
                {
                    string result = BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", String.Empty);
                    return result;
                }
            }
        }
    }
}
ну а как насчёт скорости ?
может одновременно запустить столько потоков проверок сколько и файлов ?
не умрёт ли комп если файлов около 3 000 , это же 3 000 потоков выйдет ) проц же просто ляжен на все 101%
0
Эксперт .NET
7573 / 5061 / 1204
Регистрация: 25.05.2015
Сообщений: 15,425
Записей в блоге: 14
24.02.2016, 10:11 7
Цитата Сообщение от Rynosce Посмотреть сообщение
Покажите мне где у меня косяки то ?
Постом выше, не? Вы же не читаете, не учитесь, вот и косяки повсюду, во всех темах.

Цитата Сообщение от Rynosce Посмотреть сообщение
может одновременно запустить столько потоков проверок сколько и файлов ?
не умрёт ли комп если файлов около 3 000 , это же 3 000 потоков выйдет ) проц же просто ляжен на все 101%
Юзайте PLINQ, TPL и Parallel, и не будет 3000 потоков.
Ни строчки кода, да. Всё у Шилдта же: Литература по C# для начинающих и не только
0
20 / 20 / 1
Регистрация: 03.09.2014
Сообщений: 35
24.02.2016, 10:13  [ТС] 8
Цитата Сообщение от Rius Посмотреть сообщение
Постом выше, не? Вы же не читаете, не учитесь, вот и косяки повсюду, во всех темах.
Дело в том то косяк то не мой , функцию нашёл то здесь )
автор m0nax
вот откуда её вычитал https://www.cyberforum.ru/csha... 05038.html
0
Эксперт .NET
7573 / 5061 / 1204
Регистрация: 25.05.2015
Сообщений: 15,425
Записей в блоге: 14
24.02.2016, 10:15 9
Всё равно Ваш, раз не распознали недостаток
Ну нельзя большой файл читать весь в память. Памяти столько нет.
0
20 / 20 / 1
Регистрация: 03.09.2014
Сообщений: 35
24.02.2016, 10:23  [ТС] 10
Цитата Сообщение от Rius Посмотреть сообщение
Всё равно Ваш, раз не распознали недостаток
Ну нельзя большой файл читать весь в память. Памяти столько нет.
Если честно , я не понимаю когда в память грузиться , а когда на прямую читается ...

и даже сейчас не понимаю , в памяти ли этот код будет работать ...
C#
1
2
3
4
5
6
7
8
9
10
11
12
        public static string Start(string path)
        {
            using (var md5 = MD5.Create())
            {
                using (var stream = File.OpenRead(path))
                {
                    byte[] checkSum = md5.ComputeHash(stream);
                    string result = BitConverter.ToString(checkSum).Replace("-", String.Empty);
                    return result;
                }
            }
        }
--------------------

Цитата Сообщение от Rius Посмотреть сообщение
Юзайте PLINQ, TPL и Parallel, и не будет 3000 потоков.
Ни строчки кода, да. Всё у Шилдта же: Литература по C# для начинающих и не только
А вот за это спасибо , сейчас почитаю литературу о том что это , никогда не сталкивался с ними

только я не понял это все три заимо-связанные методы ?
или как варианты ?
какой лучше ?
0
Эксперт .NET
7573 / 5061 / 1204
Регистрация: 25.05.2015
Сообщений: 15,425
Записей в блоге: 14
24.02.2016, 10:27 11
Цитата Сообщение от Rynosce Посмотреть сообщение
и даже сейчас не понимаю , в памяти ли этот код будет работать ...
https://msdn.microsoft.com/ru-... 10%29.aspx - File.OpenRead возвращает Stream,
https://msdn.microsoft.com/en-... 10%29.aspx - ComputeHash принимает Stream.
Будет кусками считывать, по мере необходимости.

Добавлено через 1 минуту
Цитата Сообщение от Rynosce Посмотреть сообщение
только я не понял это все три заимо-связанные методы ?
или как варианты ?
какой лучше ?
Это надо усвоить всё. Потом сможете составить список файлов, передать его в нужные методы, которые запустят параллельно несколько потоков, всё посчитают, дождутся завершения всех остальных потоков и вернут результат.
1
483 / 396 / 68
Регистрация: 14.02.2014
Сообщений: 1,930
24.02.2016, 12:54 12
Цитата Сообщение от Rynosce Посмотреть сообщение
странно , у меня 8 гиг оперативки , тоже 64 бита
что мешает сделать так:
C#
1
2
3
4
5
6
7
8
        void Foo(string path)
        {
            using (FileStream fs = new FileStream(path, FileMode.Open))
            {
                MD5 md5Hasher = MD5.Create();
                byte[] md5Hash = md5Hasher.ComputeHash(fs);
            }
        }
Добавлено через 2 минуты
) блин, давно не обновлял страницу, оказывается, уже решено
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.02.2016, 12:54

CRC32: Дополнить файл для получения контрольной суммы FFFFFFFF
Привет! Имеется произвольный бинарный файл. Цель: дополнить его как можно меньшим кол-вом байт,...

Upload на сервер файлов более 4 мегабайт
Подскажите пожалуйста... на сервер не загружаются файлы больше 4Mb. Что делать? Где настраивать?...

Найти все RTF файлы, захешировать эти файлы MD5 и SHA1. Потов захешированые файлы поместить в документ
Найти все RTF файлы, захешировать эти файлы MD5 и SHA1. Потов захешированые файлы поместить в...

Посоветуйте видеокарты от 384 до 768 мегабайт с низким энергопотреблением до 50 ватт и тех процессом не более 55нм
а то поставил видеокарту на 1024 мб и у меня оперативки стало на 256мб меньше материнская плата...


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

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

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