Быстрее альтернатива MD5?

Когда вы объявляете ссылочную переменную (т. е. объект), вы действительно создаете указатель на объект. Рассмотрим следующий код, в котором вы объявляете переменную примитивного типа int:

int x;
x = 10;

В этом примере переменная x является int, и Java инициализирует ее для 0. Когда вы назначаете его 10 во второй строке, ваше значение 10 записывается в ячейку памяти, на которую указывает x.

Но когда вы пытаетесь объявить ссылочный тип, произойдет что-то другое. Возьмите следующий код:

Integer num;
num = new Integer(10);

Первая строка объявляет переменную с именем num, но она не содержит примитивного значения. Вместо этого он содержит указатель (потому что тип Integer является ссылочным типом). Поскольку вы еще не указали, что указать на Java, он устанавливает значение null, что означает «Я ничего не указываю».

Во второй строке ключевое слово new используется для создания экземпляра (или создания ) объекту типа Integer и переменной указателя num присваивается этот объект. Теперь вы можете ссылаться на объект, используя оператор разыменования . (точка).

Exception, о котором вы просили, возникает, когда вы объявляете переменную, но не создавали объект. Если вы попытаетесь разыменовать num. Перед созданием объекта вы получите NullPointerException. В самых тривиальных случаях компилятор поймает проблему и сообщит вам, что «num не может быть инициализирован», но иногда вы пишете код, который непосредственно не создает объект.

Например, вы можете имеют следующий метод:

public void doSomething(SomeObject obj) {
   //do something to obj
}

В этом случае вы не создаете объект obj, скорее предполагая, что он был создан до вызова метода doSomething. К сожалению, этот метод можно вызвать следующим образом:

doSomething(null);

В этом случае obj имеет значение null. Если метод предназначен для того, чтобы что-то сделать для переданного объекта, целесообразно бросить NullPointerException, потому что это ошибка программиста, и программисту понадобится эта информация для целей отладки.

Альтернативно, там могут быть случаи, когда цель метода заключается не только в том, чтобы работать с переданным в объекте, и поэтому нулевой параметр может быть приемлемым. В этом случае вам нужно будет проверить нулевой параметр и вести себя по-другому. Вы также должны объяснить это в документации. Например, doSomething может быть записано как:

/**
  * @param obj An optional foo for ____. May be null, in which case 
  *  the result will be ____.
  */
public void doSomething(SomeObject obj) {
    if(obj != null) {
       //do something
    } else {
       //do something else
    }
}

Наконец, Как определить исключение & amp; причина использования Трассировки стека

14
задан Nick Berardi 23 September 2014 в 02:29
поделиться

5 ответов

Я надеюсь, что Вы проверяете на соответствие MD5, только если размер файла уже соответствует.

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

, Конечно, все это предполагает, что Вы просто ищете match/nomatch решение для конкретного файла.

44
ответ дан 1 December 2019 в 05:53
поделиться

просто считайте файл линейно? Кажется довольно бессмысленным считать весь файл, вычислить хеш md5 и затем сравнить хеш.

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

, Если бы у Вас уже были хеши для всех файлов в диске, имело бы смысл сравнивать их, но если необходимо вычислить их на лету, просто, кажется, нет никакого преимущества для хеширования.

я пропускающий что-то здесь? Что хеширование покупает Вас в этом случае?

5
ответ дан 1 December 2019 в 05:53
поделиться

Сначала рассмотрите то, что является действительно Вашим узким местом: сама хеш-функция или скорее скорость доступа к диску? Если Вы будете ограничены диском, то изменение алгоритма хеширования не даст Вам очень. Из Вашего описания я подразумеваю, что Вы всегда сканируете целый диск, чтобы найти, что соответствие - рассматривает создание индекса сначала, и затем только соответствуйте данному хешу против индекса, это будет намного быстрее.

6
ответ дан 1 December 2019 в 05:53
поделиться

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

Это означает, что можно использовать MD5, чтобы сказать, ли файлы отличающиеся (если MD5 отличается, файлы должны отличаться), но Вы не можете использовать MD5, чтобы сказать, ли файлы равны (если файлы равны, MD5 должен быть тем же, но если MD5 равен, файлы могли бы или не могли бы быть равными).

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

Ссылки:

5
ответ дан 1 December 2019 в 05:53
поделиться

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

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

9
ответ дан 1 December 2019 в 05:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: