January 13th, 2008 by depesz | Tags: | 7 comments »
Did it help? If yes - maybe you can help me?

i needed a way to generate ed2k urls based on existing files on my harddrive.

ed2k link looks like this:

ed2k://|file|FILENAME|FILESIZE|CHECKSUM|/

filename and filesize are of course known, but what about checksum? i tried to find some ready program to calculate them, but failed. it might be because i spent something like 3 minutes on it, but anyway – i didn't find it. so i tried to find algorithm description.

luckily there is a nice algorithms description. algorithms, as there apparently are two separate algorithms, not fully compatible with each other.

based on the information i was able to write a short perl script which does the job:

=> cat ed2ksum.pl
#!/usr/bin/perl -l
use Digest::MD4 qw(md4 md4_hex);open$f,pop or die$!;$c.=md4$b while sysread$f,$b,9728000;print uc md4_hex$c

yes, it is unreadable. but it works. first version was longer (about 15 lines), but then i decided to try to make it shorter. and shorter. and then even shorter. most probably it is not the shortest possible way, but i'm safisfied with it.

how does it work? simply:

=> ./ed2ksum.pl Slony-I-concept.pdf
E8715CD212CD75E0EE4B6C526D5BF36A

hope you'll find it useful.

  1. 7 comments

  2. # zytek
    Jan 14, 2008

    so, postgresql can’t do that? ;-)))

  3. Jan 14, 2008

    @zytek:
    nice try. of course it can. but i’m not sure if using pg for this is a good idea 🙂
    anyway, to do it i would use pl/perlu, which makes it use practically the same code.

  4. Jan 14, 2008

    new version. 7 characters shorter:
    #!/usr/bin/perl -l
    use Digest::MD4 qw(md4 md4_hex);open$f,pop or die$!;$/=\9728000;$c.=md4$_ for<$f>;print uc md4_hex$c

  5. # Morten
    Jan 18, 2008

    You don’t take into account files less than 9728000 bytes, do you? The ed2k of them is the MD4, not the MD4 of the MD4.

  6. Jan 18, 2008

    @Morten:
    well, actually i didn’t think about them. mostly because i need it only for much larger files.

  7. # val
    Apr 20, 2009

    You missed cases:
    when size is less than 9 728 000 bytes
    when size is X * 9 728 000 bytes

    For them you’ll get wrong hash.

  8. Apr 21, 2009

    @val:
    i’m not aware of any special treatment for cases where size = X * 9728000. and as for < 9728000 - check comment #04 and my reply in #05.

Sorry, comments for this post are disabled.