in reply to Fast way to check if a sort was doen

Stringifying the array can lead to incorrect results in some cases. Consider the following:

use strict; use warnings; use Digest::MD5 qw( md5 ); my @a1 = ( 'aa', 'a', '' ); print '[', join( '|', @a1 ), "]\n"; my $d1 = md5( @a1 ); my @sorted_a1 = sort @a1; print '[', join( '|', @sorted_a1 ), "]\n"; my $sorted_d1 = md5( @sorted_a1 ); printf( "Digests are %s\n", ( $d1 eq $sorted_d1 ) ? 'equal' : 'unequal' );
Prints:
[aa|a|] [|a|aa] Digests are equal

In this case, the elements in the array were completely reversed by the sort but the md5 digest was identical.

This is (partly) documented in the docs for Digest::MD5:

The result of md5("a", "b", "c") will be exactly the same as the result of md5("abc").

Replies are listed 'Best First'.
Re^2: Fast way to check if a sort was done (using stringification is *broken*)
by ikegami (Patriarch) on Jun 29, 2007 at 03:32 UTC
    my $signature = md5(pack('(J/a*)*', @array));

    should do the trick quickly.

    Update: Of course, md5 really doesn't add anything. You could just use

    my $signature = pack('(J/a*)*', @array);

      Nice solution! I didn't know about '/' in pack.

      It's not quite perfect, though. It treats the empty string and undef as equal (there may be more ways to break it - this is just the first one I thought of):

      my $signature_1 = pack( '(J/a*)*', '', undef ); my $signature_2 = pack( '(J/a*)*', undef, '' ); printf( "Signatures are %s\n", ( $signature_1 eq $signature_2 ) ? 'equal' : 'unequal' ); # eq +ual!

      These cases were not specified in the OP. I apologize for being pedantic. :-)