Звантажте контрольні суми md5 та sha1 за допомогою однієї команди!


9

Я шукаю команду або утиліти для обчислення md5 , sha1 хеш-значення однією командою.
Зараз ubuntu має sha1sumта md5sumкоманду для обчислення hashзначення.


2
Чому ти цього хочеш? Зазвичай ви хочете мати можливість перевірити хеші після їх генерації. Наприклад, для створення хеш: md5sum hosts. Потім, щоб перевірити цей результат: echo "b9adfb2e2022a3a84ba06b55eeb2dc64 hosts" | md5sum --check(повинен дати: hosts: OK)
Lekensteyn

2
припустимо, якщо ви хочете обчислити "хеш-значення" жорсткого диска 500 ГБ, тобто sha1 і md5. якщо я обчислюю по черзі (використовуючи sha1sum і md5sum), це займе подвійний час. але якщо це вдасться зробити з одними утилітами, такими як програмне забезпечення Windows, то це була б моя бажана відповідь.
MS Parmar

Відповіді:


9

Ви можете досягти цього за допомогою правильного баш-ніндзя-фу. :)

Ви знаєте процедуру обчислення одного за одним:

$ echo abc | md5sum
0bee89b07a248e27c83fc3d5951213c1  -
$ echo abc | sha1sum
03cfd743661f07975fa2f1220c5194cbaff48451  -

Редагувати: як запропонував @gertvdijk, і прочитавши трохи більше інформаційних сторінок, це можна зробити безпосередньо за допомогою tee і Process Substitution, підтримуваних сучасними оболонками, без перенаправлень. Таким чином ви можете передати свої дані в два процеси та один файл за допомогою трійника:

$ echo abc | tee >(md5sum) >(sha1sum) > output.txt

Також можливо ланцюг, якщо вам потрібно більше, але вам потрібно подбати про STDOUT з усіх підпроцесів. Це НЕ дасть вам очікуваного результату, але змішає перші дві контрольні суми разом із даними у output.txt:

$ echo abc | tee >(md5sum) >(sha1sum) | tee >(sha256sum) >(sha512sum) > output.txt

Якщо ви переспрямовуєте контрольні суми до файлу всередині заміщених процесів, ви можете зв’язати їх ланцюжками, як вам завгодно:

$ echo abc | tee >(md5sum > /tmp/md5.txt) >(sha1sum > /tmp/sha1.txt) | tee >(sha256sum > /tmp/sha256.txt) >(sha512sum > /tmp/sha512.txt) > output.txt

Ось моя початкова пропозиція без підстановки процесу, але яка дозволяє ланцюжок / рекурсивне використання без змішування даних і результатів:

$ echo abc | tee -a /proc/self/fd/2 2> >(sha1sum) > >(md5sum)
0bee89b07a248e27c83fc3d5951213c1  -
03cfd743661f07975fa2f1220c5194cbaff48451  -

Хитрість тут полягає у використанні tee, яке дублює дані в STDOUT та файл. Ми розумні, кажучи йому записувати дані у файл / proc / self / fd / 2, який завжди є дескриптором файлу STDERR поточного процесу. І за допомогою > >(program)синтаксису ми можемо перенаправляти кожен дескриптор файлу на STDIN програми замість файлу. Так само |, але з більшим контролем. > >(md5sum)перенаправляє STDOUT до md5sumпрограми, а 2> >(sha1sum)перенаправляє STDERR на sha1sumпрограму.

Зауважте, що порядок 2>і, >здається, має значення, я маю поставити 2>перше в командному рядку. Вони оцінюються справа наліво, але я не впевнений, чому це має значення.

Для цього у файлі чи на жорсткому диску слід замінити "echo abc" на cat або dd, наприклад:

dd if=/dev/sda bs=8k | tee -a /proc/self/fd/2 2> >(sha1sum) > >(md5sum)

Прекрасна річ у цьому полягає в тому, що ви можете фактично повторити та запустити кілька одночасно, а не лише два. Синтаксис стає волохатим, але це працює:

echo abc | tee -a /proc/self/fd/2 2> >(tee -a /proc/self/fd/2 2> >(sha256sum) > >(sha384sum) ) > >(sha512sum)

Якщо ви хочете зафіксувати результат і використовувати його в сценарії, це також працює:

A=$(echo abc | tee -a /proc/self/fd/2 2> >(sha1sum) > >(md5sum))

Тепер $Aце рядок, що містить увесь результат, включаючи нові рядки. Ви можете також потім проаналізувати значення:

echo "checksum=[$(echo "$A" | head -1 | cut -d " " -f 1)]"

Я не впевнений, що у вас є якісь гарантії щодо впорядкування виводу.


2
+1. teeі розумне використання перенаправлення виводу в оболонці - це шлях. Це економить багато ресурсів, особливо при читанні великих файлів.
gertvdijk

2
До речі, я думаю, вам не потрібно перенаправляти на stderr, щоб дублювати вихід потоку. Використання нижньої оболонки також зробить трюк, зберігаючи жорсткість. Дивіться мій приклад тут у публікації в блозі .
gertvdijk

@gertvdijk Правильно, заміна процесу чистіша і простіша в ланцюзі (повторювати не потрібно). Я оновлю свою відповідь.
ketil

Приємно. Я дам вам ще одну пропозицію, якщо зможу. :-)
gertvdijk

Хоча вони добре працюють для гарних невеликих файлів, ви подвоюєте зусилля та обробляєте час для більших файлів, яких я хочу уникати ...
EkriirkE

3

Не можу допомогти вам у командному рядку, але я знаю інструмент GUI, який називається quickhash

Ви можете завантажити цей інструмент з Quickhash

Опис:

Графічний інтерфейс Linux та Windows для забезпечення швидкого вибору та подальшого хешування файлів (окремо або рекурсивно у всій структурі папки) тексту та (на Linux) дисків. Призначений для Linux, але також доступний для Windows. MD5, SHA1, SHA256, SHA512 доступні. Вихідні дані скопійовано у буфер обміну або збережено як файл CSV \ HTML.


0
Here i have find one python script from source which calculate hash values. and also i find some statistics about hash value calculation.

 - `md5sum` takes 00:3:00 min to calculate 4GB USB.
 - `sha2sum` takes 00:3:01 min to calculate 4GB USB.
 - While phython script takes 3:16 min to calculate both MD5 and SHA1.

// Сценарій починаємо звідси

def get_custom_checksum(input_file_name):
    from datetime import datetime
    starttime = datetime.now()
    # START: Actual checksum calculation
    from hashlib import md5, sha1, sha224, sha384, sha256, sha512
    #chunk_size = 1 # 1 byte -- NOT RECOMENDED -- USE AT LEAST 1KB. When 1KB takes 1 min to run, 1B takes 19 minutes to run
    #chunk_size = 1024 # 1 KB
    chunk_size = 1048576 # 1024 B * 1024 B = 1048576 B = 1 MB
    file_md5_checksum = md5()
    file_sha1_checksum = sha1()

    try:
        with open(input_file_name, "rb") as f:
            byte = f.read(chunk_size)
            previous_byte = byte
            byte_size = len(byte)
            file_read_iterations = 1
            while byte:
                file_md5_checksum.update(byte)
                file_sha1_checksum.update(byte)               
                previous_byte = byte
                byte = f.read(chunk_size)
                byte_size += len(byte)
                file_read_iterations += 1
    except IOError:
        print ('File could not be opened: %s' % (input_file_name))
        #exit()
        return
    except:
        raise
    # END: Actual checksum calculation
    # For storage purposes, 1024 bytes = 1 kilobyte
    # For data transfer purposes, 1000 bits = 1 kilobit
    kilo_byte_size = byte_size/1024
    mega_byte_size = kilo_byte_size/1024
    giga_byte_size = mega_byte_size/1024
    bit_size = byte_size*8
    kilo_bit_size = bit_size/1000
    mega_bit_size = kilo_bit_size/1000
    giga_bit_size = mega_bit_size/1000
    last_chunk_size = len(previous_byte)
    stoptime = datetime.now()
    processtime = stoptime-starttime
    custom_checksum_profile = {
        'starttime': starttime,
        'byte_size': byte_size,
        'kilo_byte_size': kilo_byte_size,
        'mega_byte_size': mega_byte_size,
        'giga_byte_size': giga_byte_size,
        'bit_size': bit_size,
        'kilo_bit_size': kilo_bit_size,
        'mega_bit_size': mega_bit_size,
        'giga_bit_size': giga_bit_size,
        'file_read_iterations': file_read_iterations,
        'last_chunk_size': last_chunk_size,
        'md5_checksum': file_md5_checksum.hexdigest(),
        'sha1_checksum': file_sha1_checksum.hexdigest(),        
        'stoptime': stoptime,
        'processtime': processtime,
        }
    return custom_checksum_profile



def print_custom_checksum(input_file_name):
    custom_checksum_profile = get_custom_checksum(input_file_name)
    try:
        print 'Start Time ::', custom_checksum_profile['starttime']

custom_checksum_profile ['file_read_iterations']) # print ('Last Chunk (bytes):', custom_checksum_profile ['last_chunk_size']) print 'MD5 ::', custom_checksum_profile ['md5_checksum'] print 'SHA1 ::', custom_checksum__file_checksum_profile '] print' Stop Time :: ', custom_checksum_profile [' stoptime '] print' Час обробки :: ', custom_checksum_profile [' processtime '], за винятком TypeError: #' NoneType 'об'єкт не піддається підключенню --- в основному це має відбуватися, коли вхідний файл не вдалося відкрити #raise pass # csv вихід

import argparse
script_version='0.0.2'
parser = argparse.ArgumentParser(description='Determine and print various checksums of an input file and its size. Supported checksums are MD5, SHA1, SHA224, SHA256, SHA384, and SHA512.', version=script_version)
parser.add_argument('-f', '--file', metavar='in-file', action='store', dest='file_name', type=str, required=True, help='Name of file for which the checksum needs to be calculated')
args = parser.parse_args()
print 'Processing File ::', args.file_name
print_custom_checksum(args.file_name)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.