2010-05-11 1 views
6

У меня есть файл под названием secure.txt в c: \ temp. Я хочу запустить команду Perl из командной строки, чтобы напечатать хэш SHA1 secure.txt. Я использую ActivePerl 5.8.2. Я раньше не использовал Perl, но это самый удобный вариант, доступный прямо сейчас.Как я могу использовать Perl для получения хэша SHA1 файла из командной строки Windows?

ответ

20
perl -MDigest::SHA1=sha1_hex -le "print sha1_hex <>" secure.txt 

Параметры командной строки для Perl описаны в perlrun. Переход слева направо в команде выше:

  • -M Digest::SHA1=sha1_hex загружает Digest::SHA1 модуль во время компиляции и импорт sha1_hex, что дает дайджест в шестнадцатеричной форме.
  • -l автоматически добавляет символ новой строки в конце любого print
  • -e вводит код Perl будет выполняться

Забавная выглядящий алмаз является частным случаем readline оператора в Perl:

Нулевой дескриптор файла <> является специальным: его можно использовать для эмуляции поведения sed и awk. Вход от <> поступает либо из стандартного ввода, либо из каждого файла, указанного в командной строке. Вот как это работает: в первый раз оценивается <>, проверяется массив @ARGV, и если он пуст, $ARGV[0] установлен в "-", который при открытии дает вам стандартный ввод. Затем массив @ARGV обрабатывается как список имен файлов.

Поскольку secure.txt единственный файл с именем в командной строке, его содержимое становится аргументом sha1_hex.

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

perl -MDigest::SHA=sha1_hex -E 'say sha1_hex<>' secure.txt 

Код капли опциональный (со всеми версиями Perl) пропуск перед <>, капли -l и выключатели от -e до -E.

  • -E commandline

    ведет себя так же, как -e, за исключением того, что она неявно включает все дополнительные функции (в основном модуле компиляции). См. feature.

Один из этих дополнительных функций является say, что делает -l ненужным.

  • say FILEHANDLE LIST
  • say LIST
  • say

    Так же, как print, но неявно добавляет символ новой строки. say LIST просто аббревиатура для

    { local $\ = "\n"; print LIST } 
    

    Это ключевое слово доступно только тогда, когда функция say включена: см feature.

Если вы хотели бы иметь этот код в удобных утилитах, скажем mysha1sum.pl, а затем использовать

#! /usr/bin/perl 

use warnings; 
use strict; 

use Digest::SHA1; 

die "Usage: $0 file ..\n" unless @ARGV; 

foreach my $file (@ARGV) { 
    my $fh; 
    unless (open $fh, $file) { 
    warn "$0: open $file: $!"; 
    next; 
    } 

    my $sha1 = Digest::SHA1->new; 
    $sha1->addfile($fh); 
    print $sha1->hexdigest, " $file\n"; 

    close $fh; 
} 

Это будет вычислять дайджест для каждого файла, указанного в командной строке, и выходной формат совместим с форматом утилиты Unix sha1sum.

C:\> mysha1sum.pl mysha1sum.pl mysha1sum.pl 
8f3a7288f1697b172820ef6be0a296560bc13bae mysha1sum.pl 
8f3a7288f1697b172820ef6be0a296560bc13bae mysha1sum.pl 

Вы не сказали ли вы установили Cygwin, но если вы делаете, sha1sum является частью пакета Coreutils.

+3

+1 для гольфа Perl Golf-in-one – amphetamachine

+2

Так много информации ... Я бы +2, если бы мог! – MiffTheFox

+0

Очень ясно. Только то, что мне было нужно. Благодаря! – Jim

-1

Использование Digest::SHA1 так:

#!/usr/bin/perl -w 
use strict; 

use Digest::SHA1 qw/ sha1_hex /; 

# open file 
open IN_DATA, "<secure.txt" or die "cannot open file secure.txt for reading: $!"; 
# read in all file contents 
my $file_contents; 
{local $/; $file_contents = <IN_DATA>;} 
# close file 
close IN_DATA; 
print &sha1_hex($file_contents); 

Edit: Почему вниз голосовать? Не работает ли этот код? Не является ли это подходящим решением проблемы?

+6

Используйте локальные лексические дескрипторы файлов - 'open my $ in_data, '<', 'secure.txt' или die ...' – Ether

+0

@Ether - это вопрос личных предпочтений. – amphetamachine

+4

Есть веские основания использовать лексические ручки. См. Http://stackoverflow.com/questions/1479741/why-is-three-argument-open-calls-with-lexical-filehandles-a-perl-best-practice – daotoad

5

Пробуйте Digest::SHA модуль.

C:\> perl -MDigest::SHA -e "print Digest::SHA->new(1)->addfile('secure.txt')->hexdigest"