ดัมพ์ md5 และ sha1 checksums ด้วยคำสั่งเดียว!


9

ฉันกำลังมองหาคำสั่งหรือยูทิลิตีสำหรับการคำนวณmd5 , sha1 hash value โดยคำสั่งเดียว
ตอนนี้อูบุนตูมีsha1sumและmd5sumสั่งให้คำนวณhashค่า


2
ทำไมคุณต้องการมัน โดยปกติคุณต้องการตรวจสอบแฮชหลังจากสร้างแล้ว md5sum hostsยกตัวอย่างเช่นการสร้างกัญชา: จากนั้นในการตรวจสอบผลนี้: echo "b9adfb2e2022a3a84ba06b55eeb2dc64 hosts" | md5sum --check(ควรให้: hosts: OK)
Lekensteyn

2
สมมติว่าต้องการคำนวณ 'ค่าแฮช' ของฮาร์ดไดรฟ์ 500 GB เช่น sha1 และ md5 ถ้าฉันคำนวณทีละหนึ่ง (โดยใช้ sha1sum และ md5sum) จะใช้เวลาสองครั้ง แต่ถ้าสามารถทำได้ด้วยโปรแกรมอรรถประโยชน์เดียวเช่นเดียวกับซอฟต์แวร์ windows แล้วจะเป็นคำตอบที่ฉันต้องการ
MS Parmar

คำตอบ:


9

คุณสามารถทำสิ่งนี้ได้ด้วยการทุบตีนินจานินจา :)

คุณรู้ขั้นตอนการคำนวณทีละครั้ง:

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

แก้ไข: ตามที่ @gertvdijk แนะนำและการอ่านหน้าข้อมูลอีกเล็กน้อยสามารถทำได้โดยตรงด้วยการแทนที่ทีและการสนับสนุนกระบวนการโดยเชลล์ที่ทันสมัยโดยไม่มีการเปลี่ยนเส้นทาง วิธีนี้คุณสามารถส่งผ่านข้อมูลของคุณไปยังสองกระบวนการและหนึ่งไฟล์โดยใช้ที:

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

นอกจากนี้ยังเป็นไปได้ที่จะเชื่อมโยงถ้าคุณต้องการมากขึ้น แต่คุณต้องดูแล STDOUT จากกระบวนการย่อยทั้งหมด สิ่งนี้จะไม่ให้ผลลัพธ์ที่คาดหวังของคุณ แต่จะรวมการตรวจสอบสองรายการแรกพร้อมกับข้อมูลใน output.txt:

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

หากคุณเปลี่ยนเส้นทาง checksums ไปยังไฟล์ภายในกระบวนการทดแทนคุณสามารถเชื่อมโยงสิ่งเหล่านี้ตามที่คุณต้องการ:

$ 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 เพื่อทำซ้ำเอาต์พุตของสตรีม การใช้ subshell นั้นจะทำการหลอกลวงโดยการบำรุงรักษา stderr ดูตัวอย่างของฉันที่นี่ในบล็อกโพสต์
gertvdijk

@gertvdijk ถูกต้องการทดแทนกระบวนการนั้นสะอาดและง่ายกว่าโซ่ (คุณไม่จำเป็นต้องเรียกคืน) ฉันจะอัพเดทคำตอบของฉัน
ketil

ดี ฉันจะให้ upvote อีกถ้าคุณสามารถ :-)
gertvdijk

ในขณะที่สิ่งเหล่านี้ทำงานได้ดีสำหรับไฟล์ขนาดเล็กที่ดีคุณกำลังเพิ่มความพยายามและเวลาในการประมวลผลสำหรับไฟล์ขนาดใหญ่ที่ฉันต้องการหลีกเลี่ยง ...
EkriirkE

3

ไม่สามารถช่วยคุณในบรรทัดคำสั่ง แต่ฉันรู้ว่าเครื่องมือ GUI ชื่อเป็นquickhash

คุณสามารถดาวน์โหลดเครื่องมือนั้นได้จากQuickhash

รายละเอียด:

Linux และ Windows GUI เพื่อเปิดใช้งานการเลือกอย่างรวดเร็วและการแฮชไฟล์ (ทีละไฟล์หรือเรียกซ้ำตลอดโครงสร้างโฟลเดอร์) และดิสก์ (บน 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 (ไบต์):', custom_checksum_profile ['last_chunk_size']) พิมพ์ 'MD5 ::', custom_checksum_profile ['md5_checksum'] '] พิมพ์' Stop Time :: ', custom_checksum_profile [' stoptime '] พิมพ์' เวลาดำเนินการ :: ', 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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.