Home: Perl Programming Help: Beginner:
BigInteger

januszmk
Novice

Apr 24, 2012, 2:05 PM

Views: 3925
 BigInteger
Hi.
I have some code in C# and I am trying convert to perl.
The code:
 Code
`            BigInteger exp = new BigInteger("SOME BIG NUMBER", 10);             BigInteger n = new BigInteger("OTHER BIG NUMBER", 10);             BigInteger integer3 = new BigInteger(str.Substring(1), 0x24);             byte[] bytes = integer3.modPow(exp, n).getBytes();             ASCIIEncoding encoding = new ASCIIEncoding();             return new string(encoding.GetChars(bytes));`
the second argument of constructor in BigInteger class is a base system.
the str is the string , something like:
 Quote
_f4eoy18ien92q667yex54u6xqyd2u6e2j0kjkvtesj4gcbkij6yq93ms7kx4yzxx0gdmj9vrhk7yns371ormeg5j44jkm727tg3
anyway, the final string that is return is "patyczkowona1".
I tried to do this in perl, with using Math::BigInt;.
I found some functions in net that convert an byte array to BigInt and BigInt to array:
 Code
`# Calculate the bit-width of cells on this system.  sub count_bits {     my \$i = 0;     my \$q = ~0x0;      # Set all bits     while ( \$q ) {     # All shifted out?         \$q = \$q << 1;  # Shift left         \$i++;          # Accum shifts     }     return \$i;         # Return bit-width }  my \$bits    = count_bits;       # System bit-width. my \$cells   = int( \$bits / 8 ); # max bytes in array my \$mask    = ~0x0;             # Full mask = 0xF* my \$top_bit = ~( \$mask >> 1 );  # High mask = 0x80*  ########################## # END N-BIT SYSTEM CHECK # ##########################  # Convert a BigInt to an array. sub bint_to_array {   my \$quo = shift;   my \$msk = Math::BigInt->new(\$mask);   my @cls;   until ( \$quo->is_zero() ) {     my \$rem = \$quo->copy();      # Lest modify ruin.     \$rem->band(\$msk);            # REM = LSC     \$quo->brsft(\$bits);          # QUO = Cells above     unshift @cls, \$rem->bstr();  # Keep remainder   }   return @cls; }  # Convert an array to a BigInt. sub array_to_bint {     my @cls = @_;     my \$out = Math::BigInt->new(0);     my \$i = 0;     while ( @_ ) {         my \$lsc = Math::BigInt->new( pop @_ );  # LSC         \$lsc->blsft(\$bits * \$i);                # Shift up         \$out->bior(\$lsc);                       # OR to LSC         ++\$i;     }     return \$out; }`

First, I am converting my string to ascii table, next, this ascii table to BigInt, then I am using bmodpow() function and convert result to array:
 Code
`my \$string = "f4eoy18ien92q667yex54u6xqyd2u6e2j0kjkvtesj4gcbkij6yq93ms7kx4yzxx0gdmj9vrhk7yns371ormeg5j44jkm727tg3"; my @ascii  = unpack("C*", \$string); my \$x = array_to_bint(@ascii);  my \$exp = "1699226779513586444311853417832813053444275415713267420973354241696037822738978485422119265005494628039077923965408489035118957525416966246759228390003017"; my \$n = "8496133897567932221559267089164065267221377078566337104866771208480189113695076911576868324903413008512741498700587851315525414979963642608998181269527941";  \$x->bmodpow(\$exp,\$n);  my @a = bint_to_array   (\$x);  my \$z; foreach \$z (@a) {   print "arg: \$z\n"; }`
But, the results is not like supposed to be:
 Quote
arg: 8660100782654598831
arg: 15621194053667428015
arg: 13895005360354588697
arg: 7950417416029500606
arg: 12330079340979623579
arg: 145443755943421736
arg: 8563019593306281932
arg: 2707167814207797994
every number supposed to be a ascii number.
I tried to convert every argument of @ascii to base36 (encode_base36() in Math::Base36), but then when I do "my \$x = array_to_bint(@ascii);" then \$x return "NaN"

Does anyone have any idea what am I doing wrong?

histrung
Novice

Apr 29, 2012, 10:01 AM

Views: 3873
 Re: [januszmk] BigInteger
Check this a little with small numbers. See if the answer is correct for you data.

 Code
`#!/usr/bin/perl  use Math::BigInt; use Math::Base36 ':all';  my \$b36 = 'f4eoy18ien92q667yex54u6xqyd2u6e2j0kjkvtesj4gcbkij6yq93ms7kx4yzxx0gdmj9vrhk7yns371ormeg5j44jkm727tg3'; my \$exp = Math::BigInt->new('1699226779513586444311853417832813053444275415713267420973354241696037822738978485422119265005494628039077923965408489035118957525416966246759228390003017');  my \$n = Math::BigInt->new('8496133897567932221559267089164065267221377078566337104866771208480189113695076911576868324903413008512741498700587851315525414979963642608998181269527941');    \$x = Math::BigInt->new(decode_base36(\$b36)); \$x->bmodpow(\$exp,\$n);  print "\nAns:  ".\$x->bstr()."\n\n";`
Output:
 Code
`\$ ./big.pl   Ans:  8903715056186744936505705128241  \$`

januszmk
Novice

May 1, 2012, 5:37 AM

Views: 3830
 Re: [histrung] BigInteger
No, it's not that simple. The result must be a array with ascii numbers.
I see that I will have to rewrite (or try) class from c#

histrung
Novice

May 1, 2012, 6:03 AM

Views: 3816
 Re: [januszmk] BigInteger
What do you mean by ASCII? Can't you just split string result and convert to ASCII if needed?
 Code
`@nums = split(//,\$x->bstr());`

januszmk
Novice

May 1, 2012, 6:17 AM

Views: 3809
 Re: [histrung] BigInteger
I can't, from 65 to 90 ascii codes are A-Z, from 97 to 122 are a-z, from 48 to 57 are 0-9, and that is why I need result in array of ascii codes, and when I convert from that array to string, then I have to get a string "patyczkowona1"

histrung
Novice

May 1, 2012, 6:31 AM

Views: 3802
 Re: [januszmk] BigInteger
If you want it in base36 just call
 Code
`\$str = encode_base36(\$x);`

januszmk
Novice

May 1, 2012, 12:51 PM

Views: 3754
 Re: [histrung] BigInteger
Not exactly.
This is the BigInteger class from one of project in c#: http://wklej.org/hash/a919cf6f489/
when Biginteger class is "executed" in code that I gave in first post, then this:
 Code
`public BigInteger(string value, int radix)`
constructor is executing.
I thought that there can be a easy way to do this in perl, but I was wrong

(This post was edited by januszmk on May 1, 2012, 12:52 PM)

januszmk
Novice

May 3, 2012, 4:21 PM

Views: 2553
 Re: [januszmk] BigInteger
Ok, I was wrong, I found some library in c++ which is doing almost the same work like in this class in c# and the result was the same like in script you gave me.
I have one more question, could you look at this class http://wklej.org/hash/a919cf6f489/ at the funcion public byte[] getBytes(), and tell me, if bstr() in Math::BigInt is giving the same result? If not, any idea how to do this?

(This post was edited by januszmk on May 3, 2012, 4:21 PM)