Can this be done as a Perl subroutine rather than an Inline C widget ?
Yes
Are there advantages in doing it via Inline C ?
Yes. The actual Vim code is C so all I did was rip the required code out of Vim and drop it into Inline C. Actually I could not resist cleaning it up a bit but that's another story. Add the fact that C is much faster than doing it in Perl, it is now done in C/XS and I have no desire to port it to Perl just so it can be slower.
Porting is fairly easy, but not trivial. The thing that makes it non trivial is that most encryption code utilises the natural rollover of integer types. Things get a bit odd in Perl in a DWIM sort of way which is not identical to C - as a result you need to know how to fix those issues.
use Inline 'C';
use constant UNSIGNED_MAX => 2**32-1;
printf "Perl: %u\t%s\n", UNSIGNED_MAX, UNSIGNED_MAX;
printf "Perl: %u\t%s\n", (UNSIGNED_MAX+1),(UNSIGNED_MAX+1);
printf "Perl: %u\t%s\n", (UNSIGNED_MAX+2),(UNSIGNED_MAX+2);
func( UNSIGNED_MAX );
__END__
__C__
int func( unsigned int arg ) {
printf( "C: %u\n", arg );
printf( "C: %u\n", arg+1 );
printf( "C: %u\n", arg+2 );
return 0;
}
This shows you the main issue:
Perl: 4294967295 4294967296
Perl: 4294967295 4294967297
Perl: 4294967295 4294967298
C: 4294967295
C: 0
C: 1
As you can see C and Perl produce different results at the rollover point.
|