Don't do math in terms of digits or strings. Do math in terms of numbers. Digits are just a way of viewing numbers, they aren't numbers themselves.
in reply to XOR'ing to calculate a hex checksum
You appear to be converting all your incoming bytes into hex before we even get to look at it in your checksum() routine, and then going through some painful conversion work to turn the pairs of hex digits back into bytes. I'm going to ignore that, and assume you have an array of @bytes instead.
my $total = 0;
$total += $_ for @bytes;
$check = ($total & 0xFF) ^ 0xFF;
Once you have your check value, then you can decide how to display it (if it needs displaying at all).
[ e d @ h a l l e y . c c ]