代码之家  ›  专栏  ›  技术社区  ›  Benedikt Waldvogel assylias

计算音频文件的校验和而不考虑头

  •  5
  • Benedikt Waldvogel assylias  · 技术社区  · 16 年前

    我想以编程方式创建音频文件(mp3、ogg vorbis、flac)的sha1校验和。 要求校验和应该是稳定的 即使标题(如ID3)改变 .
    注意:音频文件没有CRC

    这就是我现在尝试的:

    1)使用Perl和 MPEG::Audio::Frame

    my $sha1 = Digest::SHA1->new;
    while (my $frame = MPEG::Audio::Frame->read(\*FH)) {
        $sha1->add($frame->content());
    }
    

    2)使用python和 libmad (pymad)

    mf = mad.MadFile(path)
    sha1 = hashlib.sha1()
    
    while 1:
        buf = mf.read()
        if (buf is None):
            break
        sha1.update(buf)
    

    3)使用 mp3cat

    > mp3cat - - < file.mp3 | sha1sum
    

    但是,这些方法都没有提供 稳定的 校验和。即,在 一些 使用重新标记文件后更改校验和的大小写 picard .

    有没有图书馆已经提供了我想要的?
    我不在乎编程语言

    更新: 我进一步调试了这个案子。 libmad校验和不一致似乎发生在libmad得到一些解码错误的情况下,比如 “哈夫曼数据溢出(0x0238)” . 因为这在很多mp3文件中都会发生,所以我不确定它是否真的表示一个损坏的文件

    5 回复  |  直到 6 年前
        1
  •  3
  •   Tobias R    16 年前

    如果你正在寻找稳定的散列,为实际的音乐,你可能想看 libOFA . 您当前的方法将为您提供不同的结果,因为格式可以有嵌入的标记。另外,如果你想要两个不同的文件返回相同的散列,你需要考虑像比特率和采样频率。

    另一方面,libofa可以提供一个稳定的散列,可以在格式和不同编码之间使用。可能是你想要的?

        2
  •  2
  •   Chris Julian Kunkel    9 年前

    我需要一些工具来快速检查我的mp3/ogg库是否仍然有效。 对于mp3,我找到mp3md5.py( http://snipplr.com/view/4025/mp3-checksum-in-id3-tag/ )它完成了这项工作,但并不是ogg vorbis的简单工具,但我编写了一个小bash脚本来完成这项工作。 这两个工具都应该允许修改comment/id3tag。

    #!/bin/bash
    
    # This bash script appends an MD5SUM to the vorbiscomment and/or verifies it if it exists
    # Later modification of the vorbis comment does not alter the MD5SUM
    # Julian M.K.
    
    FILE="$1"
    
    if [[ ! -f "$FILE" || ! -r "$FILE" || ! -w "$FILE" ]] ; then
      echo "File $FILE" does not exist or is not readable or writable
      exit 1
    fi
    
    OLDCRC=`vorbiscomment "$FILE" | grep ^CRC=|cut -d "=" -f 2`
    NEWCRC=`ogginfo "$FILE" |grep "Total data length:" |cut -d ":" -f 2 | md5sum |cut -d " " -f 1`
    
    if [[ "$OLDCRC" == "" ]] ; then
      echo "ADDED $FILE  $NEWCRC"
      vorbiscomment -a -t "CRC=$NEWCRC" "$FILE" 
      # rewrite CRC to get proper data length, I dont know why this is necessary
      NEWCRC=`ogginfo "$FILE" |grep "Total data length:" |cut -d ":" -f 2 | md5sum |cut -d " " -f 1`
      vorbiscomment -w -t "CRC=$NEWCRC" "$FILE" 
    elif [[ "$OLDCRC" == "$NEWCRC" ]]  ; then
      echo "VERIFIED $FILE"
    else
      echo "FAILURE $FILE -- $OLDCRC - $NEWCRC"
    fi
    
        3
  •  0
  •   GEOCHET S.Lott    16 年前

    贝尼,如果我是你,(我正在做一些与你想做的非常相似的事情),我会散列MP3数据块。(首先将其提取到原始数据,然后将其写入磁盘,这样您就知道要处理的是什么)。然后,修改id3标记。再次散列数据。现在,如果它发生了变化,请比较两组原始数据并找出变化的地方。很可能,你在某个地方越界了。如果我记得的话,mp3文件以类似ff f8的开头。好吧,至少框架是这样的。

    我对你的发现很感兴趣,因为我仍然在写我所有的代码来处理指纹等,而且还没有到真正的散列。

        4
  •  0
  •   mivk    16 年前

    我也在做同样的事。我用MD5代替SHA1。我开始使用mp3tag(www.mp3tag.de/en/)导出音频校验和;然后制作了一个类似于您的perl脚本来执行同样的操作。然后我从测试文件中删除了所有标签,音频校验和保持不变。

    这是脚本:

    use MPEG::Audio::Frame;
    use Digest::MD5 qw(md5_hex);
    use strict;
    
    my $file = 'E:\Music\MP3\Russensoul\01 - 5nizza , Soldat (Russensoul - Russensoul).mp3';
    my $mp3tag_audio_md5 = lc '2EDFBD62995A46A45CEEC08C1F303486';
    
    my $md5 = Digest::MD5->new;
    
    open(FILE, $file) or die "Cannot open $file : $!\n";
    binmode FILE;
    
    while(my $frame = MPEG::Audio::Frame->read(\*FILE)){
        $md5->add($frame->asbin);
    }
    
    print '$md5->hexdigest  : ', $md5->hexdigest, "\n",
          'mp3tag_audio_md5 : ', $mp3tag_audio_md5,  "\n",
          ;
    

    有没有可能,无论你用什么来修改你的标签有时也会修改MP3的标题?

        5
  •  0
  •   Мокин Василий    6 年前

    有一种简单而稳定的方法可以做到这一点。只需复制一份文件并删除其中的所有标记(例如,使用tuntor.id3),然后获取结果文件的哈希和。

    这种方法的唯一缺点是它的性能。