Acme-Tools
view release on metacpan or search on metacpan
=cut
#TODO: @arr2=conv(\@arr1,"from","to") # should be way faster than:
#TODO: @arr2=map conv($_,"from","to"),@arr1
#TODO: conv(123456789,'b','h'); # h converts to something human-readable
our %conv=(
length=>{
m => 1,
_m => 1,
meter => 1,
meters => 1,
metre => 1,
metres => 1,
km => 1000,
mil => 10000, #scandinavian #also: inch/1000!
in => 0.0254,
inch => 0.0254,
inches => 0.0254,
ft => 0.0254*12, #0.3048 m
feet => 0.0254*12, #0.3048 m
yd => 0.0254*12*3, #0.9144 m
yard => 0.0254*12*3, #0.9144 m
yards => 0.0254*12*3, #0.9144 m
fathom => 0.0254*12*3*2, #1.8288 m
fathoms => 0.0254*12*3*2, #1.8288 m
chain => 0.0254*12*3*22, #20.1168 m
chains => 0.0254*12*3*22, #20.1168 m
furlong => 0.0254*12*3*22*10, #201.168 m
furlongs=> 0.0254*12*3*22*10, #201.168 m
mi => 0.0254*12*3*22*10*8, #1609.344 m
mile => 0.0254*12*3*22*10*8, #1609.344 m
miles => 0.0254*12*3*22*10*8,
league => 0.0254*12*3*22*10*8*3, #4828.032 m
leagues => 0.0254*12*3*22*10*8*3, #4828.032 m
yard_imp => 0.914398416,
yard_imperical => 0.914398416,
NM => 1852, #nautical mile
nmi => 1852, #nautical mile
'nautical mile' => 1852,
'nautical miles' => 1852,
micron => 1e-6,
microns => 1e-6,
micrometre => 1e-6,
micrometres => 1e-6,
'Ã
' => 1e-10,
'ångstrøm' => 1e-10,
'angstrom' => 1e-10,
fm => 1e-15,
fermi => 1e-15, #in honour of Enrico Fermi
fermis => 1e-15, #in honour of Enrico Fermi
femtometer => 1e-15, #derived from "femten" (=fifteen in Norwegian and Danish)
femtometre => 1e-15,
femtometers => 1e-15, #derived from "femten" (=fifteen in Norwegian and Danish)
femtometres => 1e-15,
attometer => 1e-18, #derived from "atten/atton" (=eighteen)
attometre => 1e-18,
attometers => 1e-18, #derived from "atten/atton" (=eighteen)
attometres => 1e-18,
ly => 299792458*3600*24*365.25,
lightyear => 299792458*3600*24*365.25, # = 9460730472580800 by def
ls => 299792458, #light-second
au => 149597870700, # by def: meters earth to sun
astronomical_unit => 149597870700,
'astronomical unit' => 149597870700,
pc => 149597870700*648000/$PI, #3.0857e16 = 3.26156 ly
_pc => 149597870700*648000/$PI,
parsec => 149597870700*648000/$PI,
attoparsec => 149597870700*648000/$PI/1e18,
apc => 149597870700*648000/$PI/1e18,
planck => 1.61619997e-35, #planck length
#Norwegian (old) lengths:
tomme => 0.0254,
tommer => 0.0254,
fot => 0.0254*12, #0.3048m
alen => 0.0254*12*2, #0.6096m
favn => 0.0254*12*2*3, #1.8288m
kvart => 0.0254*12*2/4, #0.1524m a quarter alen
#--https://upload.wikimedia.org/wikipedia/commons/e/eb/English_length_units_graph.svg
twip => 0.0254 / 6 / 12 / 20,
point => 0.0254 / 6 / 12,
pica => 0.0254 / 6,
line => 0.0254 / 12,
thou => 0.0254 / 1000,
barleycorn => 0.0254 / 3,
poppyseed => 0.0254 / 3 / 4,
finger => 0.0254 / 6 / 12 * 63,
palm => 0.0254 * 3,
digit => 0.0254 * 3 / 4,
nail => 0.0254 * 3 / 4 * 3,
rack => 0.0254 * 1.75,
stick => 0.0254 * 2,
hand => 0.0254 * 2 * 2,
foot => 0.0254 * 2 * 2 * 3,
shaftment => 0.0254 * 3 * 2,
span => 0.0254 * 3 * 3,
ell => 0.0254 * 3 * 3 * 5,
pace => 0.0254 * 3 * 2 * 5,
step => 0.0254 * 3 * 2 * 5,
cubit => 0.0254 * 3 * 2 * 3,
rod => 0.0254 * 3 * 2 * 3 * 11,
link => 0.0254 * 3 * 2 * 3 * 11 / 25,
yard => 0.0254 * 2 * 2 * 3 * 3,
grade => 0.0254 * 3 * 2 * 5 * 2,
rope => 0.0254 * 3 * 2 * 5 * 2 * 4,
skein => 0.0254 * 3 * 3 * 5 * 96, # 96 ell
fathom => 0.0254 * 2 * 2 * 3 * 3 * 2, # 2 yard
spindle => 0.0254 * 3 * 3 * 5 * 96 * 120, # 120 skein
gunter_chain => 0.0254 * 2 * 2 * 3 * 3 * 2 * 11, # 11 fathom
ramsden_chain => 0.0254 * 3 * 2 * 5 * 2 * 4 * 5, # 5 rope
shackle => 0.0254 * 2 * 2 * 3 * 3 * 2 * 15, # 15 fathom
cable => 0.0254 * 2 * 2 * 3 * 3 * 2 * 100, # 100 fathom
furlong => 0.0254 * 2 * 2 * 3 * 3 * 2 * 11 * 10, # 10 gunter_chain, 220 yard
roman_mile => 0.0254 * 3 * 2 * 5 * 2 * 4 * 5 * 50, # 50 ramsden_chain
statute_mile => 0.0254 * 2 * 2 * 3 * 3 * 2 * 11 * 10 * 8, # 8 furlong
nautic_mile => 0.0254 * 2 * 2 * 3 * 3 * 2 * 100 * 10, # 10 cable
league => 0.0254 * 2 * 2 * 3 * 3 * 2 * 100 * 10 * 5, # 5 nautic_mile
siriometer => 149597870700*1e6, # 1 million astronomical units
},
mass =>{ #https://en.wikipedia.org/wiki/Unit_conversion#Mass
g => 1,
liter => 0.001,
liters => 0.001,
litre => 0.001,
litres => 0.001,
gal => 231 * 0.0254**3, #3.785411784 L = 0.003785411784 m3, #231 cubic inches
gallon => 231 * 0.0254**3,
gallons => 231 * 0.0254**3,
gallon_us => 231 * 0.0254**3, #231 cubic inches
gallon_wine => 231 * 0.0254**3, #queen anne's gallon
gallon_ale => 282 * 0.0254**3, #beer
gallon_corn => 268.8*0.0254**3, #corn, or winchester gallon
gallon_uk => 4.54609/1000, #constant 4.54609 from definition
gallon_imp => 4.54609/1000, #imperial
gallon_us_dry => 4.40488377086/1000, # ~ 9.25**2*pi*2.54**3/1000 L
#hogshead, gill, pail, jigger, jackpot, The Science of Measurement - A Historical Survey (Klein)
cm3 => 0.01**3, #0.001 L
in3 => 0.0254**3, #0.016387064 L
ft3 => (0.0254*12)**3,
tablespoon=> 3.785411784/256, #14.78676478125 mL
tsp => 3.785411784/256/3, #4.92892159375 mL
teaspoon => 3.785411784/256/3, #4.92892159375 mL
floz => 3.785411784/128, #fluid ounce US
floz_uk => 4.54609/160, #fluid ounce UK
pint => 4.54609/8000, #0.56826125 L
pint_uk => 4.54609/8000,
pint_imp => 4.54609/8000,
pint_us => 3.785411784/8000, #0.473176473
quart => 4.54609/4000, #2*pint
pottle => 4.54609/2000, #2*quart = gallon_uk/2
#therm => 2.74, #? 100000BTUs? (!= thermie)
#thm => 2.74, #? (!= th)
fat => 42*231*2.54**3/1e6,
bbl => 42*231*2.54**3/1e6, #oil barrel ~159 liters https://en.wikipedia.org/wiki/Barrel_(unit)
Mbbl => 42*231*2.54**3/1e3, #mille (thousand) oil barrels, M er mille her, ikke mega!
MMbbl => 42*231*2.54**3, #mille mille (million) oil barrels
drum => 0.208, #208 L
container => 33.1e3, #container20
container20 => 33.1e3,
container40 => 67.5e3,
container40HC => 75.3e3,
container45HC => 86.1e3,
firkin => 282*0.0254**3 * 8, #8 gallon_ale
#Norwegian:
meterfavn => 2 * 2 * 0.6, #fire wood/ved 2.4 m3
storfavn => 2 * 2 * 3, #fire wood/ved 12 m3
},
time =>{
s => 1,
_s => 1,
sec => 1,
second => 1,
seconds => 1,
m => 60,
min => 60,
minute => 60,
minutes => 60,
h => 60*60,
hr => 60*60,
hour => 60*60,
hours => 60*60,
d => 60*60*24,
dy => 60*60*24,
day => 60*60*24,
days => 60*60*24,
w => 60*60*24*7,
week => 60*60*24*7,
weeks => 60*60*24*7,
mo => 60*60*24 * 365.2425/12,
mon => 60*60*24 * 365.2425/12,
month => 60*60*24 * 365.2425/12,
quarter => 60*60*24 * 365.2425/12 * 3, #3 months
season => 60*60*24 * 365.2425/12 * 3, #3 months
y => 60*60*24 * 365.2425, # 365+97/400 #97 leap yers in 400 years
year => 60*60*24 * 365.2425,
years => 60*60*24 * 365.2425,
yjulian => 60*60*24 * 365.25, # 365+1/4
y365 => 60*60*24 * 365, # finance/science
ycommon => 60*60*24 * 365, # finance/science
ygregorian => 60*60*24 * 365.2425, # 365+97/400
#ygaussian => 365+(6*3600+9*60+56)/(24*3600), # 365+97/400
ytropical => 60*60*24 * 365.24219,
ysideral => 365.256363004,
ySI => 60*60*24*365.25, #31556925.9747
decade => 10 * 60*60*24*365.2425,
biennium => 2 * 60*60*24*365.2425,
triennium => 3 * 60*60*24*365.2425,
olympiad => 4 * 60*60*24*365.2425,
lustrum => 5 * 60*60*24*365.2425,
indiction => 15 * 60*60*24*365.2425,
jubilee => 50 * 60*60*24*365.2425,
century => 100 * 60*60*24*365.2425,
millennium => 1000 * 60*60*24*365.2425,
shake => 1e-8,
moment => 3600/40, #1/40th of an hour, used by Medieval Western European computists
ke => 864, #1/100th of a day, trad Chinese, 14m24s
fortnight => 14*24*3600,
tp => 5.3910632e-44, #planck time, time for ligth to travel 1 planck length
nanocentury => 100 * 60*60*24*365.2425 / 1e9, #3.156 ~ pi seconds, response time limit (usability)
warhol => 15*60, #"fifteen minutes of fame"
},
speed=>{
'm/s' => 1,
'_m/s' => 1,
mps => 1,
mph => 1609.344/3600,
'mi/h' => 1609.344/3600,
kmh => 1/3.6,
kmph => 1/3.6,
'km/h' => 1/3.6,
kmt => 1/3.6, # t=time(=hour) or temps (scandinavian and french and dutch)
'km/t' => 1/3.6,
kt => 1852/3600,
kts => 1852/3600,
kn => 1852/3600,
knot => 1852/3600,
knots => 1852/3600,
knop => 1852/3600, #scandinavian
c => 299792458, #speed of light, exact due to definition of meter
mach => 340.3, #speed of sound
machs => 340.3,
fps => 0.3048, #0.0254*12
ftps => 0.3048,
'ft/s' => 0.3048,
},
acceleration=>{
'm/s2' => 1,
'mps2' => 1,
g => 9.80665,
g0 => 9.80665,
#0-100kmh or ca 0-60 mph x seconds...
},
temperature=>{ #http://en.wikipedia.org/wiki/Temperature#Conversion
C=>1, F=>1, K=>1, celsius=>1, fahrenheit=>1, kelvin=>1
},
radioactivity=>{
Bq => 1,
becquerel => 1,
curie => 3.7e10,
},
current=> {
A => 1,
_A => 1,
'N/m2' => 2e-7,
},
charge=>{
e => 1,
_e => 1,
C => 6.24150964712042e+18,
coulomb => 6.24150964712042e+18,
As => 6.24150964712042e+18,
#Faraday unit of charge ???
},
power=> {
W => 1,
_W => 1,
'J/s' => 1,
Jps => 1,
hp => 746,
point => 1/32, #used in navigation
hexacontade => 1/60,
binary_degree => 1/256,
binary_radian => 1/256,
brad => 1/256,
},
money =>{ # rates at 18th feb 2018
NOK => 1.000000000, #norwegian kroner
AED => 2.118503, #united arab emirates dirham
ARS => 0.393725, #argentina peso
AUD => 6.162408, #australian dollar
BCH => 12118.36327559, #bitcoin cash
BGN => 4.937892, #bulgarian lev
BHD => 20.692023, #bahrain dinar
BND => 5.931982, #brunei dollar
BRL => 2.407647, #brazilian real
BTC => 84864.0984477, #bitcoin
BWP => 0.825478, #botswana pulaa
CAD => 6.201377, #canadian dollar
CHF => 8.391971, #switzerland franc
CLP => 0.013110, #chili peso
CNY => 1.226451, #china yuan/renminbi
COP => 0.00274549, #colombian peso
CZK => 0.380706, #czech koruna
DKK => 1.295957, #danish kroner
ETC => 257.8101864767, #ethereum-classic
ETH => 7410.657012902, #ethereum
EUR => 9.657677, #euro
GBP => 10.913727, #great britain pound, british pound
'£' => 10.913727, #great britain pound, british pound symbol
HKD => 0.994705, #hong kong dollar
HRK => 1.301015, #croatian kuna
HUF => 0.030922, #hungarian forint
IDR => 0.00057358, #indonesian rupia
ILS => 2.191990, #israel new shekel
INR => 0.121070, #indian rupee
IRR => 0.00020984, #iranian rial
ISK => 0.077647, #icelandic kroner
JPY => 0.073271, #japanish yen
KRW => 0.00729673, #south korean won
KWD => 25.925147, #kuwait dinar
KZT => 0.024338, #kazakhstanian tenge
LKR => 0.050121, #sri lanka rupee
LTC => 1782.926421562, #litecoin
LYD => 5.866758, #libyan dinar
MUR => 0.239306, #mauritius
MXN => 0.418798, #mexico peso
MYR => 1.998096, #malaysian ringgit
NPR => 0.075316, #nepal rupee
NZD => 5.745187, #new zealand dollar
OMR => 20.234592, #oman rial
PHP => 0.148869, #philippines peso
PKR => 0.070338, #pakistan rupee
PLN => 2.319848, #poland zloty
QAR => 2.137418, #qatar rial
RON => 2.070137, #romaina new nei
RUB => 0.137791, #russia rouble / rubel
SAR => 2.074720, #saudi arabia riyal
SEK => 0.976704, #swedish kroner
SGD => 5.931982, #singapore dollar
THB => 0.248282, #thailand baht
TRY => 2.076265, #turkish new lira
TTD => 1.150931, #trinidad/tobago dollar
TWD => 0.267321, #taiwan dollar
USD => 7.780201, #us dollar
'$' => 7.780201, #us doller, symbol
VEF => 0.778994, #venezuelan bolivares fuertes
XBT => 84864.0984477, #synonym for BTC
XRP => 8.96808208868, #ripple
ZAR => 0.667117, #south africa rand
},
numbers =>{
dec=>1,hex=>1,bin=>1,oct=>1,roman=>1, des=>1,#des: spelling error in v0.15-0.16
dusin=>1,dozen=>1,doz=>1,dz=>1,gross=>144,gr=>144,gro=>144,great_gross=>12*144,small_gross=>10*12,
}
);
our $conv_prepare_time=0;
our $conv_prepare_money_time=0;
sub conv_prepare {
my %b =(da =>1e+1, h =>1e+2, k =>1e+3, M =>1e+6, G =>1e+9, T =>1e+12, P =>1e+15, E =>1e+18, Z =>1e+21, Y =>1e+24, H =>1e+27);
my %big =(deca=>1e+1, hecto=>1e+2, kilo =>1e+3, mega =>1e+6, giga=>1e+9, tera=>1e+12, peta =>1e+15, exa =>1e+18, zetta=>1e+21, yotta=>1e+24, hella=>1e+27);
my %s =(d =>1e-1, c =>1e-2, m =>1e-3,'µ' =>1e-6, u=>1e-6, n =>1e-9, p =>1e-12, f =>1e-15, a =>1e-18, z =>1e-21, y =>1e-24);
my %small=(deci=>1e-1, centi=>1e-2, milli=>1e-3, micro =>1e-6, nano=>1e-9, pico=>1e-12, femto=>1e-15, atto=>1e-18, zepto=>1e-21, yocto=>1e-24);
# myria=> 10000 #obsolete
# demi => 1/2, double => 2 #obsolete
# lakh => 1e5, crore => 1e7 #south asian
my %x = (%s,%b);
for my $type (keys%conv) {
for(grep/^_/,keys%{$conv{$type}}) {
my $c=$conv{$type}{$_};
delete$conv{$type}{$_};
my $unit=substr($_,1);
$conv{$type}{$_.$unit}=$x{$_}*$c for keys%x;
}
}
$conv_prepare_time=time();
}
our $Currency_rates_url = 'http://calthis.com/currency-rates';
our $Currency_rates_expire = 6*3600;
sub conv_prepare_money {
eval {
require LWP::Simple;
my $td=$^O=~/^(?:linux|cygwin)$/?"/tmp":"/tmp"; #hm wrong!
my $fn="$td/acme-tools-currency-rates.data";
if( !-e$fn or time() - (stat($fn))[9] >= $Currency_rates_expire){
LWP::Simple::getstore($Currency_rates_url,"$fn.$$.tmp"); # get ... see getrates.cmd
die "nothing downloaded" if !-s"$fn.$$.tmp";
rename "$fn.$$.tmp",$fn;
chmod 0666,$fn;
}
my $d=readfile($fn);
my %r=$d=~/^\s*([A-Z]{3}) +(\d+\.\d+)\b/gm;
$r{lc($_)}=$r{$_} for keys%r;
#warn serialize([minus([sort keys(%r)],[sort keys(%{$conv{money}})])],'minus'); #ARS,AED,COP,BWP,LVL,BHD,NPR,LKR,QAR,KWD,LYD,SAR,KZT,CLP,IRR,VEF,TTD,OMR,MUR,BND
#warn serialize([minus([sort keys(%{$conv{money}})],[sort keys(%r)])],'minus'); #LTC,I44,BTC,BYR,TWI,NOK,XDR
$conv{money}={%{$conv{money}},%r} if keys(%r)>20;
};
carp "conv: conv_prepare_money (currency conversion automatic daily updated rates) - $@\n" if $@;
$conv{money}{"m$_"}=$conv{money}{$_}/1000 for qw/BTC XBT/;
$conv_prepare_money_time=time();
the number divided by 1099511627776 with two decimals and "TB" behind otherwise
Examples:
print bytes_readable(999); # 999 B
print bytes_readable(1000); # 1000 B
print bytes_readable(1001); # 0.98 kB
print bytes_readable(1024); # 1.00 kB
print bytes_readable(1153433.6); # 1.10 MB
print bytes_readable(1181116006.4); # 1.10 GB
print bytes_readable(1209462790553.6); # 1.10 TB
print bytes_readable(1088516511498.24*1000); # 990.00 TB
print bytes_readable(1088516511498.24*1000, 3); # 990.000 TB
print bytes_readable(1088516511498.24*1000, 1); # 990.0 TB
=cut
sub bytes_readable {
my $bytes=shift();
my $d=shift()||2; #decimals
return undef if !defined $bytes;
return "$bytes B" if abs($bytes) <= 2** 0*1000; #bytes
return sprintf("%.*f kB",$d,$bytes/2**10) if abs($bytes) < 2**10*1000; #kilobyte
return sprintf("%.*f MB",$d,$bytes/2**20) if abs($bytes) < 2**20*1000; #megabyte
return sprintf("%.*f GB",$d,$bytes/2**30) if abs($bytes) < 2**30*1000; #gigabyte
return sprintf("%.*f TB",$d,$bytes/2**40) if abs($bytes) < 2**40*1000; #terrabyte
return sprintf("%.*f PB",$d,$bytes/2**50); #petabyte, exabyte, zettabyte, yottabyte
}
=head2 sec_readable
Time written as C< 14h 37m > is often more humanly comprehensible than C< 52620 seconds >.
print sec_readable( 0 ); # 0s
print sec_readable( 0.0123 ); # 0.0123s
print sec_readable(-0.0123 ); # -0.0123s
print sec_readable( 1.23 ); # 1.23s
print sec_readable( 1 ); # 1s
print sec_readable( 9.87 ); # 9.87s
print sec_readable( 10 ); # 10s
print sec_readable( 10.1 ); # 10.1s
print sec_readable( 59 ); # 59s
print sec_readable( 59.123 ); # 59.1s
print sec_readable( 60 ); # 1m 0s
print sec_readable( 60.1 ); # 1m 0s
print sec_readable( 121 ); # 2m 1s
print sec_readable( 131 ); # 2m 11s
print sec_readable( 1331 ); # 22m 11s
print sec_readable(-1331 ); # -22m 11s
print sec_readable( 13331 ); # 3h 42m
print sec_readable( 133331 ); # 1d 13h
print sec_readable( 1333331 ); # 15d 10h
print sec_readable( 13333331 ); # 154d 7h
print sec_readable( 133333331 ); # 4yr 82d
print sec_readable( 1333333331 ); # 42yr 91d
=cut
sub sec_readable {
my $s=shift();
my($h,$d,$y)=(3600,24*3600,365.25*24*3600);
!defined$s ? undef
:!length($s) ? ''
:$s<0 ? '-'.sec_readable(-$s)
:$s<60 && int($s)==$s
? $s."s"
:$s<60 ? sprintf("%.*fs",int(3+-log($s)/log(10)),$s)
:$s<3600 ? int($s/60)."m " .($s%60) ."s"
:$s<24*3600 ? int($s/$h)."h " .int(($s%$h)/60)."m"
:$s<366*24*3600 ? int($s/$d)."d " .int(($s%$d)/$h)."h"
: int($s/$y)."yr ".int(($s%$y)/$d)."d";
}
=head2 int2roman
Converts integers to roman numbers.
B<Examples:>
print int2roman(1234); # prints MCCXXXIV
print int2roman(1971); # prints MCMLXXI
(Adapted subroutine from Peter J. Acklam, jacklam(&)math.uio.no)
I = 1
V = 5
X = 10
L = 50
C = 100 (centum)
D = 500
M = 1000 (mille)
See also L<Roman>.
See L<http://en.wikipedia.org/wiki/Roman_numbers> for more.
=head2 roman2int
roman2int("MCMLXXI") == 1971
=cut
#alternative algorithm: http://www.rapidtables.com/convert/number/how-number-to-roman-numerals.htm
#see also t/17_roman.t sub int2roman_old
sub int2roman {
my $n=shift;
!defined$n ? undef
: !length($n) ? ""
: $n<0 ? "-".int2roman(-$n)
: int($n)!=$n ? croak"int2roman: $n is not an integer"
# : $] >= 5.014 ? #s///r modifier introduced in perl v5.14
# ("I" x $n)
# =~s,I{1000},M,gr #unnecessary, but speedup for n>1000
# =~s,I{100},C,gr #unnecessary, but speedup for n>100
# =~s,I{10},X,gr #unnecessary, but speedup for n>10
# =~s,IIIII,V,gr
# =~s,IIII,IV,gr
# =~s,VV,X,gr
# =~s,VIV,IX,gr
# =~s,XXXXX,L,gr
# =~s,XXXX,XL,gr
# - git push origin master
# - http://pause.perl.org/
# - tegnsett/utf8-kroell
# - https://rt.cpan.org/Dist/Display.html?Queue=Acme-Tools
# http://en.wikipedia.org/wiki/Birthday_problem#Approximations
# memoize_expire() http://perldoc.perl.org/Memoize/Expire.html
# memoize_file_expire()
# memoize_limit_size() #lru
# memoize_file_limit_size()
# memoize_memcached http://search.cpan.org/~dtrischuk/Memoize-Memcached-0.03/lib/Memoize/Memcached.pm
# hint on http://perl.jonallen.info/writing/articles/install-perl-modules-without-root
# sub mycrc32 { #http://billauer.co.il/blog/2011/05/perl-crc32-crc-xs-module/ eller String::CRC32::crc32 som er 100 x raskere enn Digest::CRC::crc32
# my ($input, $init_value, $polynomial) = @_;
# $init_value = 0 unless (defined $init_value);
# $polynomial = 0xedb88320 unless (defined $polynomial);
# my @lookup_table;
# for (my $i=0; $i<256; $i++) {
# my $x = $i;
# for (my $j=0; $j<8; $j++) {
# if ($x & 1) {
# $x = ($x >> 1) ^ $polynomial;
# } else {
# $x = $x >> 1;
# }
# }
# push @lookup_table, $x;
# }
# my $crc = $init_value ^ 0xffffffff;
# foreach my $x (unpack ('C*', $input)) {
# $crc = (($crc >> 8) & 0xffffff) ^ $lookup_table[ ($crc ^ $x) & 0xff ];
# }
# $crc = $crc ^ 0xffffffff;
# return $crc;
# }
#
# $maybe_valid_utf8 =~ # https://stackoverflow.com/questions/11709410/regex-to-detect-invalid-utf-8-string
# m/\A(
# [\x09\x0A\x0D\x20-\x7E] # ASCII, or rather: [\x00-\x7F]
# | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
# | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
# | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
# | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
# | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
# | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
# | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
# )*\z/x;
=head1 HISTORY
Release history
0.27 Feb 2020 Small fixes for some platforms
0.26 Jan 2020 Convert subs: base bin2dec bin2hex bin2oct dec2bin dec2hex dec2oct
hex2bin hex2dec hex2oct oct2bin oct2dec oct2hex
Array subs: joinr perm permute permute_continue pile sortby subarrays
Other subs: btw in_iprange ipnum_ok iprange_ok opts s2t
0.24 Feb 2019 fixed failes on perl 5.16 and older
0.23 Jan 2019 Subs: logn, egrep, which. More UTF-8 "oriented" (lower, upper, ...)
Commands: zsize, finddup, due (improved), conv (improved, [MGT]?Wh
and many more units), due -M for stdin of filenames.
0.22 Feb 2018 Subs: subarr, sim, sim_perm, aoh2sql. command: resubst
0.21 Mar 2017 Improved nicenum() and its tests
0.20 Mar 2017 Subs: a2h cnttbl h2a log10 log2 nicenum rstddev sec_readable
throttle timems refa refaa refah refh refha refhh refs
eachr globr keysr popr pushr shiftr splicer unshiftr valuesr
Commands: 2bz2 2gz 2xz z2z
0.172 Dec 2015 Subs: curb openstr pwgen sleepms sleepnm srlz tms username
self_update install_acme_command_tools
Commands: conv due freq wipe xcat (see "Commands")
0.16 Feb 2015 bigr curb cpad isnum parta parth read_conf resolve_equation
roman2int trim. Improved: conv (numbers currency) range ("derivatives")
0.15 Nov 2014 Improved doc
0.14 Nov 2014 New subs, improved tests and doc
0.13 Oct 2010 Non-linux test issue, resolve. improved: bloom filter, tests, doc
0.12 Oct 2010 Improved tests, doc, bloom filter, random_gauss, bytes_readable
0.11 Dec 2008 Improved doc
0.10 Dec 2008
=head1 SEE ALSO
L<https://github.com/kjetillll/Acme-Tools>
=head1 AUTHOR
Kjetil Skotheim, E<lt>kjetil.skotheim@gmail.comE<gt>
=head1 COPYRIGHT
2008-2020, Kjetil Skotheim
=head1 LICENSE
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
=cut
( run in 1.145 second using v1.01-cache-2.11-cpan-9581c071862 )