Calculate audio checksum excluding header

I want to programmatically create a SHA1 checksum of audio files (MP3, Ogg Vorbis, Flac). The requirement is that the checksum must be stable even if the header (e.g. ID3) changes .
Note. Sound files do not have CRC

This is what I tried to:

1) Read + Hash all MPEG frames using Perl and MPEG :: Audio :: Frame

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

2) Decoding + Hashing all MPEG frames using Python and libmad (pymad)

mf = mad.MadFile(path)
sha1 = hashlib.sha1()

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

3) Using mp3cat

> mp3cat - - < file.mp3 | sha1sum

. , picard.

, , ?
...

Update: . libmad, , , libmad , " (0x0238)". mp3 , , ...

+5
5

, libOFA. , . , , , , .

libOFA, , , . , ?

+3

, , MP3/OGG. MP3 mp3md5.py(http://snipplr.com/view/4025/mp3-checksum-in-id3-tag/), , OGG Vorbis, bash script, . /ID 3Tag.

#!/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
+2

, , ( - , ), - . ( , , ). ID3. . , , , . , -. , MP3 - FF F8. , , .

, , .., .

0

. MD5 SHA1. mp3tag (www.mp3tag.de/en/); Perl script , . , .

script:

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?

0

There is a simple stable way to do this. Just make a copy of the file and remove all tags from it (for example, using mutagen.id3) and take the hash amount of the resulting file.

The only drawback of this method is its performance.

0
source

All Articles