Skip Menu |

This queue is for tickets about the Math-BigInt CPAN distribution.

Report information
The Basics
Id: 122681
Status: resolved
Priority: 0/
Queue: Math-BigInt

People
Owner: Nobody in particular
Requestors: CDRAKE [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: 1.999815



Subject: Feature contribution proposal: from_base() [for base64, trinary, and any other arbitrary formats]
There is no handling for base64-encoded numbers. There is also no handling for arbitrary other bases, nor is there an easy-to-use handler for variables bases. I propose to submit a patch to you which will implement the following:- $x = Math::BigInt->from_base($base,$string,$optional_collation_sequence); e.g. $x = Math::BigInt->from_base(64,"Hello_World","0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/"); # 20333681053883128807 $x = Math::BigInt->from_base(3,"12000110202101022210102000112010020100121"); # 20333681053883128807 Find attached a stand-alone solution containing my proposed patch implementation code. Please let me know if you will include this proposed submission or not (and if so - any changes or extra features (corresponding to_base?) you want): I prefer not to waste anyone's time writing and testing and submitting a patch if nobody is going to use it! Chris.
Subject: base-anything.pl
#!/usr/bin/perl -w our $VERSION='0.20110825'; =head1 NAME base-anything.pl - Converts "numbers" to and from arbitrary bases =head1 SYNOPSIS base-anything.pl [options] number Options: -from the base of the incoming number -to the base of the number to output -seq use alternative collation sequence besides: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!"#$%&'()*+,-./:;<=>?@[\]^_`{|}? -iseq like -seq - but for the input base only -oseq like -seq - but for the output base only -pad Length to use for fixed-width output -help brief help message -man full documentation =head1 SUBROUTINES The following information is for maintenance programmer reference. nb: perl -e 'use integer; $a=2**63-1; print $a' => 9223372036854775807 =cut ###################################################################### use strict; no utf8; # Source code contains no unusual characters use warnings; # same as -w switch above use bytes; # Needed to prevent mixups when exchanging unicode data with Oracle use Getopt::Long; # Commandline argument parsing use Pod::Usage; # Inbuilt documentation helper use Math::BigInt lib => 'GMP'; # Warning - must use GMP, or else RSA ops each take over a minute to complete my %arg; # We store copies of commandline arguments in here my($norm,$red,$grn,$yel,$nav,$blu,$save,$rest,$clr)=("\033[0m","\033[31;1m","\033[32;1m","\033[33;1m","\033[34;1m","\033[36;1m","\033[s","\033[u","\033[K"); my @collseq=(0..9,'A'..'Z','a'..'z',split('',q{!"#$%&'()*+,-./:;<=>?@[\\]^_`\{|\}~? }."\007\007\007")); # Parse options, and print help/manual if requested. &GetOptions('help|?' => \$arg{'help'}, 'man' => \$arg{'man'}, 'from|f=i' => \$arg{'from'}, 'to|t=i' => \$arg{'to'}, 'seq|s=s' => \$arg{'seq'}, 'iseq|i=s' => \$arg{'iseq'}, 'oseq|o=s' => \$arg{'oseq'}, 'pad=i' => \$arg{'pad'}, ) or &pod2usage(2); &pod2usage(1) if ($arg{'help'}||($arg{'from'}<1)||($arg{'to'}<1)||($ARGV[0] eq '')); &pod2usage(-exitstatus => 0, -verbose => 2) if $arg{'man'}; @collseq=split('',$arg{'seq'}) if(defined $arg{'seq'}); my @ocollseq=@collseq; @collseq=split('',$arg{'iseq'}) if(defined $arg{'iseq'}); @ocollseq=split('',$arg{'oseq'}) if(defined $arg{'oseq'}); my %collseq;foreach my $i (0..$#collseq){$collseq{$collseq[$i]}=$i}; # Build Fast lookup table print &base_anything(from=>$arg{'from'},to=>$arg{'to'},in=>$ARGV[0],pad=>$arg{'pad'}); ###################################################################### =head2 base_anything Convert a base-anything input number/string into any other output base (within the max integer size contraints of the running architecture!) eg: &base_anything(from=>10,to=>39,in=>999999999999) = '7B7JL0a0'; =cut ###################################################################### sub base_anything { my(%c)=@_; my $res=Math::BigInt->new(0); my $base=Math::BigInt->new(1); my $a=''; my %collseq;foreach my $i (0..$#collseq){$collseq{$collseq[$i]}=$i}; # Build Fast base_anything lookup table # Convert the input to internal representation while((my $c=chop($c{'in'})) ne '') { my $add=$base->copy(); $add->bmul($collseq{$c}); $res->badd($add); $base->bmul($c{'from'}); } # Convert internal representation to the output while($res->is_pos()) { # >0 my($quo,$rem)=$res->bdiv($c{'to'}); $a=$ocollseq[$rem] . $a; $res=$quo; # ($res-$r) / $c{'to'}; } if(defined($c{'pad'})) { $a=$ocollseq[0] . $a while(length($a)<$c{'pad'}); } return $a; } # base_anything __END__ =head1 AUTHOR Chris Drake <christopher@pobox.com> =head1 BUGS =over 3 =item * Revision 0.20110825; no known problems as yet. =back =head1 CHANGE HISTORY =over 3 =item * 0.20110825 Introduced change history into POD =back =head1 SEE ALSO http://perldoc.perl.org/integer.html =head1 COPYRIGHT E<32>This file Copyright (C) 2011 Chris Drake. All Rights Reserved.E<10> Portions Copyright (C) 1989 through 2011 Chris Drake. All Rights Reserved.E<10> B<This program is NOT free software.>E<10> B<It must not be distributed without prior written consent.> =cut