Nano Hash - криптовалюты, майнинг, программирование

Хеширование байтов изображения с помощью SHA-256 приводит к множеству случайных коллизий, что я делаю не так?

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

К сожалению, я получаю много случайных коллизий: 68 изображений, которые не имеют идентичных байтов, с использованием одного и того же извлечения пикселей (ниже) из 6000 хешей изображений с одинаковым значением. Мне кажется, это безумное количество столкновений. Кроме того, я сбросил вычисленные байты из пиксельных данных в файл, а затем попытался:

echo -n [byteDumpFile] | sha256sum

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

Вот как я получаю данные о пикселях:

    imageBytes = new byte[4 * width * height];
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {

            // grab color information
            int argb = image.getRGB(x, y);

            // a,r,g,b ordered bytes per this pixel. the values are always 0-255 so the byte cast is safe
            int offset = y * width;
            int pushX = x * 4;
            imageBytes[pushX + offset] = (byte) ((argb >> 24) & 0xff);
            imageBytes[pushX + 1 + offset] = (byte) ((argb >> 16) & 0xff);
            imageBytes[pushX + 2 + offset] = (byte) ((argb >> 8) & 0xff);
            imageBytes[pushX + 3 + offset] = (byte) (argb & 0xff);

        }
    }

Затем я вычисляю хэш с помощью класса MessageDigest:

    MessageDigest digest = MessageDigest.getInstance("SHA-256");
    digest.reset();


    for (int i = 0; i < imageBytes.length; i++)
    {
        digest.update(imageBytes[i]);
    }

    String hashString = new String(encodeHex(digest.digest()));

где encodeHex просто:

   private static String encodeHex(byte data[])
    {
        StringBuilder hex = new StringBuilder(2 * data.length);
        for (byte b : data)
        {
            hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));
        }

    return hex.toString();
}

Ответы:


1

Я думаю, что offset неправильно рассчитывается. Должен быть:

int offset = y * width * 4;

Лучшим способом создания imageBytes может быть _4 _ ; это позволяет вам просто put каждый байт последовательно без вычисления индекса. Кроме того, его можно использовать напрямую с MessageDigest.

14.06.2012
  • @TylerBettilyon, можешь поделиться своим окончательным решением? 14.11.2015
  • Извините, @Tarion, я сделал это для компании, но я больше там не работаю и у меня больше нет доступа к базе кода. 02.01.2016

  • 2

    пытаться

    digest.update(imageBytes);
    
    14.06.2012

    3

    Я это придумал. Основываясь на комментариях выше:

    private String calculateHash(BufferedImage img) throws NoSuchAlgorithmException {
        final int width = img.getWidth();
        final int height = img.getHeight();
        final ByteBuffer byteBuffer = ByteBuffer.allocate(4 * width * height);
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                // grab color information
                int argb = img.getRGB(x, y);
    
                // a,r,g,b ordered bytes per this pixel. the values are always 0-255 so the byte cast is safe
                byteBuffer.put((byte) ((argb >> 24) & 0xff));
                byteBuffer.put((byte) ((argb >> 16) & 0xff));
                byteBuffer.put((byte) ((argb >> 8) & 0xff));
                byteBuffer.put((byte) (argb & 0xff));
            }
        }
    
    
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        digest.reset();
    
        byte[] hashBytes = digest.digest(byteBuffer.array());
        return Base64Utils.encodeToString(hashBytes);
    }
    
    13.11.2015
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..