checksum calculation (perl?)

I'm using AIX 4.3.2 with ksh and would like to set up an alphanumeric paging script which is compatible with the New Zealand Telecom TAP protocol, which uses a checksum of the message to verify its accuracy.  To achieve this, I would like a script (perferably perl) which performs the following:

1. Take as input, a file which may include printable and "unprintable" characters.

2. Produce as output, a number which is the sum of the ASCII values of all the charaters in the file.

Eg: If the file contains:
This would add up as follows:
Char   ASCII
  1      49
  2      50
  3      51
  \n     10
  A      65
  \n     10
Total:  235
So, the output should be 235 (decimal).

If you've done that, here's an optional part for extra points:
1. Take the last 12 bits of the above.
2. Convert each group of 4 bits into the ASCII chars 48 ("0") to 63 ("?").
Eg: In the case of a checksum like 12667 (decimal), this converts to binary:
  11 0001 0111 1011
The last 12 bits are:
  0001 0111 1011
Or in decimal:
  1 7 11
And you can just add 48 (decimal) to each of these to get:
  49 55 59
Which can be represented by ASCII chars:
  1 7 ;
So the output should be:

I will probably "reject" non-perl answers until I give up waiting for perl answers, since perl is my preference.

LVL 12
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

perl -0777 -ne 'print unpack"%32C*",$_' file
Check this code ...


$file = "file.bin";
open(F, $file);
$/ = undef;
    $sum = 0;
    for( $i=0; $i<length($_); $i++)
        $sum += ord( substr($_, $i, 1) );

# Now checksum in $sum;

$t1 = $sum & 15   + 48;
$t2 = $sum & 240  + 48;
$t3 = $sum & 3840 + 48;

$result = chr($t3) . chr($t2) . chr($t1);
print $result;

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
perl -0777 -ne 'print "000\n"^pack"C*",map{hex}split//,sprintf"%03x",unpack"%12C*",$_' file.bin
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

tel2Author Commented:
maxkir & ozo,

Thanks for your good answers and sorry for the delay in checking them out.

I didn't intentionally "Accept" maxkir's answer, I think the EE system must time-out and auto-accept answers after so much time.  IS THAT CORRECT?

ozo's first answer satisfied the compulsory part of my question, so he deserved full points for that.

When I ran maxkir's script, which was attempting to answer both parts, but in the "123\nA\n" example, it gave me: "  +" (ie: space, space, +), instead of the correct answer: "0>;".
Your script looks good, is much more readable than ozo's, and obviously took some work, and I thank you for that, but I think it must have a bug (either that, or I tested it wrongly).  Anyway, you sort-of deserve the points you received, for the time you spent.

ozo later gave another of his cryptic specials, which gives me a full and  correct result.  Well done ozo, and thanks.  Some day I hope to understand your code.

I will open a dummy question titled "Points for ozo (Q.10254245)" so I can award ozo points.

Thanks to both of you for your time.
Is there some part of the code that you don't understand?
I'd hope one could learn something from understanding it.
tel2Author Commented:
Although I'm a programmer, I've never seen such a cryptic (or concise/powerful) language as Perl.

I basically don't understand any of your script, starting with the "-0777".

If you could spare the time to break it down and explain it, I'd be most grateful.  If you want points for that, let me know what it's worth first.

-0777 is explained in
perldoc perlrun

unpack, sprintf, split, map, hex, pack, and print are explained in
perldoc -f print
perldoc -f pack

^ is explained in
perldoc perlop

If you want any furthur explaination after reading the documentation, you can ask for clarification of whatever is unclear.
You can also experiment yourself to see what it's doing at each step.
e.g. try just
perl -0777 -ne 'print sprintf"%03x",unpack"%12C*",$_' file.bin
which prints the sum in hexadecimal
tel2Author Commented:
Thanks heaps ozo.
Good to have you on the team!
perl -0777 -pe '($_=sprintf"%03x\n",unpack"%12C*",$_)=~tr/0-9a-f/0-?/' file.bin
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.