2 Star 10 Fork 0

唯尔默.序 / nginx-tool

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
LbBigInt.pas 82.08 KB
一键复制 编辑 原始数据 按行查看 历史
wilmerxu 提交于 2020-11-21 15:46 . add nginx tool code
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617
{$I LockBox.inc}
unit LbBigInt;
{-bigInteger math routines}
interface
uses
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
{$IFDEF UsingCLX}
Types,
{$ENDIF}
Sysutils,
LbRandom;
const
cLESS_THAN = shortInt(-1);
cEQUAL_TO = shortInt(0);
cGREATER_THAN = shortInt(1);
cPOSITIVE = True;
cNEGATIVE = False;
{ LbInteger record }
type
LbIntBuf = packed record
dwLen : integer; {!!03}
pBuf : pByte;
end;
LbInteger = packed record
bSign : Boolean;
dwUsed : integer; {!!03}
IntBuf : LbIntBuf;
end;
{ TLbBigInt }
type
TLbBigInt = class
protected {private}
FI : LbInteger;
procedure setSign(value : Boolean);
function getSign : Boolean;
function GetSize : integer; {!!03}
function GetIntStr : string;
function GetIntBuf : pByte;
public
constructor Create(ALen : Integer);
destructor Destroy; override;
procedure Add(I2 : TLbBigInt);
procedure Subtract(I2 : TLbBigInt);
procedure Multiply(I2 : TLbBigInt);
procedure Divide(I2 : TLbBigInt);
procedure Modulus(I2 : TLbBigInt);
function ModInv(Modulus : TLbBigInt) : Boolean;
procedure PowerAndMod(Exponent : TLbBigInt; modulus : TLbBigInt);
procedure AddByte(b : byte);
procedure SubtractByte(b : byte);
procedure MultiplyByte(b : byte);
procedure DivideByte(b : byte);
procedure ModByte(b : byte);
procedure Clear;
procedure Trim;
function Compare(I2 : TLbBigInt) : ShortInt;
function IsZero : Boolean;
function IsOne : Boolean;
function IsOdd : Boolean;
function IsEven : Boolean;
function IsComposite(Iterations : Cardinal) : Boolean;
function Abs(I2 : TLbBigInt) : ShortInt;
procedure ReverseBits;
procedure ReverseBytes;
function GetBit(bit : Integer) : Boolean;
procedure Shr_(_shr : Integer);
procedure Shl_(_shl : Integer);
procedure OR_(I2 : TLbBigInt);
procedure XOR_(I2 : TLbBigInt);
procedure RandomBytes(Count : Cardinal);
procedure RandomPrime(Iterations : Byte);
procedure RandomSimplePrime;
procedure Copy(I2 : TLbBigInt);
procedure CopyLen(I2 : TLbBigInt; Len : Integer);
procedure CopyByte(b : byte);
procedure CopyWord(w : word);
procedure CopyDWord(d : dword);
procedure CopyBuffer(const Buf; BufLen : Integer);
procedure Append(I : TLbBigInt);
procedure AppendByte(b : byte);
procedure AppendWord(w : word);
procedure AppendDWord(d : dword);
procedure AppendBuffer(const Buf; BufLen : Integer);
procedure Prepend(I : TLbBigInt);
procedure PrependByte(b : byte);
procedure PrependWord(w : word);
procedure PrependDWord(d : dword);
procedure PrependBuffer(const Buf; BufLen : Integer);
function ToBuffer(var Buf; BufLen : Integer) : integer;
function GetByteValue( place : integer ) : Byte;
property Sign : Boolean
read getSign write setSign;
property Int : LbInteger
read FI;
property IntBuf : pByte
read GetIntBuf;
property IntStr : string
read GetIntStr;
property Size : integer {!!03}
read GetSize;
end;
implementation
uses
{$IFDEF Debugging} Dialogs, {$ENDIF}
LbUtils, LbConst;
const { misc local constants }
cBYTE_POSSIBLE_VALUES = 256;
cDEFAULT_PRECISION = 64;
cUSE_DEFAULT_PRECISION = 0;
cDEFAULT_SIGN = cPOSITIVE;
cDEFAULT_USED = 0;
cAPPEND_ARRAY = 0;
cPREPEND_ARRAY = 1;
cDEFAULT_MAX_PRECISION = 256;
const { simple prime table }
cTotalSimplePrimes = (258 * 8);
cTotalSimpleBytePrimes = 53; { %80 elimination }
cTotalSimple2KPrimes = 303;
type
pBiByteArray = ^TBiByteArray;
pBiWordArray = ^TBiWordArray;
// TBiByteArray = array[0..65535] of Byte;
TBiByteArray = array[0..pred(maxint)] of Byte;
TBiWordArray = array[0..pred(maxint div 2 )] of word;
const
cMaxBigIntSize = SizeOf( TByteArray );
const
{ source :
http://www.geocities.com/ResearchTriangle/Thinktank/2434/prime/primenumbers.html }
SimplePrimes : array[ 0..pred(cTotalSimplePrimes)] of DWord = ( {!!.01}
2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , // 1
23 , 29 , 31 , 37 , 41 , 43 , 47 , 53 , // 2
59 , 61 , 67 , 71 , 73 , 79 , 83 , 89 , // 3
97 , 101 , 103 , 107 , 109 , 113 , 127 , 131 , // 4
137 , 139 , 149 , 151 , 157 , 163 , 167 , 173 , // 5
179 , 181 , 191 , 193 , 197 , 199 , 211 , 223 , // 6
227 , 229 , 233 , 239 , 241 , 251 , 257 , 263 , // 7 < 256 = 53
269 , 271 , 277 , 281 , 283 , 293 , 307 , 311 , // 8
313 , 317 , 331 , 337 , 347 , 349 , 353 , 359 , // 9
367 , 373 , 379 , 383 , 389 , 397 , 401 , 409 , // 10
419 , 421 , 431 , 433 , 439 , 443 , 449 , 457 , // 11
461 , 463 , 467 , 479 , 487 , 491 , 499 , 503 , // 12
509 , 521 , 523 , 541 , 547 , 557 , 563 , 569 , // 13
571 , 577 , 587 , 593 , 599 , 601 , 607 , 613 , // 14
617 , 619 , 631 , 641 , 643 , 647 , 653 , 659 , // 15
661 , 673 , 677 , 683 , 691 , 701 , 709 , 719 , // 16
727 , 733 , 739 , 743 , 751 , 757 , 761 , 769 , // 17
773 , 787 , 797 , 809 , 811 , 821 , 823 , 827 , // 18
829 , 839 , 853 , 857 , 859 , 863 , 877 , 881 , // 19
883 , 887 , 907 , 911 , 919 , 929 , 937 , 941 , // 20
947 , 953 , 967 , 971 , 977 , 983 , 991 , 997 , // 21
1009 , 1013 , 1019 , 1021 , 1031 , 1033 , 1039 , 1049 , // 22
1051 , 1061 , 1063 , 1069 , 1087 , 1091 , 1093 , 1097 , // 23
1103 , 1109 , 1117 , 1123 , 1129 , 1151 , 1153 , 1163 , // 24
1171 , 1181 , 1187 , 1193 , 1201 , 1213 , 1217 , 1223 , // 25
1229 , 1231 , 1237 , 1249 , 1259 , 1277 , 1279 , 1283 , // 26
1289 , 1291 , 1297 , 1301 , 1303 , 1307 , 1319 , 1321 , // 27
1327 , 1361 , 1367 , 1373 , 1381 , 1399 , 1409 , 1423 , // 28
1427 , 1429 , 1433 , 1439 , 1447 , 1451 , 1453 , 1459 , // 29
1471 , 1481 , 1483 , 1487 , 1489 , 1493 , 1499 , 1511 , // 30
1523 , 1531 , 1543 , 1549 , 1553 , 1559 , 1567 , 1571 , // 31
1579 , 1583 , 1597 , 1601 , 1607 , 1609 , 1613 , 1619 , // 32
1621 , 1627 , 1637 , 1657 , 1663 , 1667 , 1669 , 1693 , // 33
1697 , 1699 , 1709 , 1721 , 1723 , 1733 , 1741 , 1747 , // 34
1753 , 1759 , 1777 , 1783 , 1787 , 1789 , 1801 , 1811 , // 35
1823 , 1831 , 1847 , 1861 , 1867 , 1871 , 1873 , 1877 , // 36
1879 , 1889 , 1901 , 1907 , 1913 , 1931 , 1933 , 1949 , // 37
1951 , 1973 , 1979 , 1987 , 1993 , 1997 , 1999 , 2003 , // 38 < 2000 = 303
2011 , 2017 , 2027 , 2029 , 2039 , 2053 , 2063 , 2069 , // 39
2081 , 2083 , 2087 , 2089 , 2099 , 2111 , 2113 , 2129 , // 40
2131 , 2137 , 2141 , 2143 , 2153 , 2161 , 2179 , 2203 , // 41
2207 , 2213 , 2221 , 2237 , 2239 , 2243 , 2251 , 2267 , // 42
2269 , 2273 , 2281 , 2287 , 2293 , 2297 , 2309 , 2311 , // 43
2333 , 2339 , 2341 , 2347 , 2351 , 2357 , 2371 , 2377 , // 44
2381 , 2383 , 2389 , 2393 , 2399 , 2411 , 2417 , 2423 , // 45
2437 , 2441 , 2447 , 2459 , 2467 , 2473 , 2477 , 2503 , // 46
2521 , 2531 , 2539 , 2543 , 2549 , 2551 , 2557 , 2579 , // 47
2591 , 2593 , 2609 , 2617 , 2621 , 2633 , 2647 , 2657 , // 48
2659 , 2663 , 2671 , 2677 , 2683 , 2687 , 2689 , 2693 , // 49
2699 , 2707 , 2711 , 2713 , 2719 , 2729 , 2731 , 2741 , // 50
2749 , 2753 , 2767 , 2777 , 2789 , 2791 , 2797 , 2801 , // 51
2803 , 2819 , 2833 , 2837 , 2843 , 2851 , 2857 , 2861 , // 52
2879 , 2887 , 2897 , 2903 , 2909 , 2917 , 2927 , 2939 , // 53
2953 , 2957 , 2963 , 2969 , 2971 , 2999 , 3001 , 3011 , // 54
3019 , 3023 , 3037 , 3041 , 3049 , 3061 , 3067 , 3079 , // 55
3083 , 3089 , 3109 , 3119 , 3121 , 3137 , 3163 , 3167 , // 56
3169 , 3181 , 3187 , 3191 , 3203 , 3209 , 3217 , 3221 , // 57
3229 , 3251 , 3253 , 3257 , 3259 , 3271 , 3299 , 3301 , // 58
3307 , 3313 , 3319 , 3323 , 3329 , 3331 , 3343 , 3347 , // 59
3359 , 3361 , 3371 , 3373 , 3389 , 3391 , 3407 , 3413 , // 60
3433 , 3449 , 3457 , 3461 , 3463 , 3467 , 3469 , 3491 , // 61
3499 , 3511 , 3517 , 3527 , 3529 , 3533 , 3539 , 3541 , // 62
3547 , 3557 , 3559 , 3571 , 3581 , 3583 , 3593 , 3607 , // 63
3613 , 3617 , 3623 , 3631 , 3637 , 3643 , 3659 , 3671 , // 64
3673 , 3677 , 3691 , 3697 , 3701 , 3709 , 3719 , 3727 , // 65
3733 , 3739 , 3761 , 3767 , 3769 , 3779 , 3793 , 3797 , // 66
3803 , 3821 , 3823 , 3833 , 3847 , 3851 , 3853 , 3863 , // 67
3877 , 3881 , 3889 , 3907 , 3911 , 3917 , 3919 , 3923 , // 68
3929 , 3931 , 3943 , 3947 , 3967 , 3989 , 4001 , 4003 , // 69
4007 , 4013 , 4019 , 4021 , 4027 , 4049 , 4051 , 4057 , // 70
4073 , 4079 , 4091 , 4093 , 4099 , 4111 , 4127 , 4129 , // 71
4133 , 4139 , 4153 , 4157 , 4159 , 4177 , 4201 , 4211 , // 72
4217 , 4219 , 4229 , 4231 , 4241 , 4243 , 4253 , 4259 , // 73
4261 , 4271 , 4273 , 4283 , 4289 , 4297 , 4327 , 4337 , // 74
4339 , 4349 , 4357 , 4363 , 4373 , 4391 , 4397 , 4409 , // 75
4421 , 4423 , 4441 , 4447 , 4451 , 4457 , 4463 , 4481 , // 76
4483 , 4493 , 4507 , 4513 , 4517 , 4519 , 4523 , 4547 , // 77
4549 , 4561 , 4567 , 4583 , 4591 , 4597 , 4603 , 4621 , // 78
4637 , 4639 , 4643 , 4649 , 4651 , 4657 , 4663 , 4673 , // 79
4679 , 4691 , 4703 , 4721 , 4723 , 4729 , 4733 , 4751 , // 80
4759 , 4783 , 4787 , 4789 , 4793 , 4799 , 4801 , 4813 , // 81
4817 , 4831 , 4861 , 4871 , 4877 , 4889 , 4903 , 4909 , // 82
4919 , 4931 , 4933 , 4937 , 4943 , 4951 , 4957 , 4967 , // 83
4969 , 4973 , 4987 , 4993 , 4999 , 5003 , 5009 , 5011 , // 84
5021 , 5023 , 5039 , 5051 , 5059 , 5077 , 5081 , 5087 , // 85
5099 , 5101 , 5107 , 5113 , 5119 , 5147 , 5153 , 5167 , // 86
5171 , 5179 , 5189 , 5197 , 5209 , 5227 , 5231 , 5233 , // 87
5237 , 5261 , 5273 , 5279 , 5281 , 5297 , 5303 , 5309 , // 88
5323 , 5333 , 5347 , 5351 , 5381 , 5387 , 5393 , 5399 , // 89
5407 , 5413 , 5417 , 5419 , 5431 , 5437 , 5441 , 5443 , // 90
5449 , 5471 , 5477 , 5479 , 5483 , 5501 , 5503 , 5507 , // 91
5519 , 5521 , 5527 , 5531 , 5557 , 5563 , 5569 , 5573 , // 92
5581 , 5591 , 5623 , 5639 , 5641 , 5647 , 5651 , 5653 , // 93
5657 , 5659 , 5669 , 5683 , 5689 , 5693 , 5701 , 5711 , // 94
5717 , 5737 , 5741 , 5743 , 5749 , 5779 , 5783 , 5791 , // 95
5801 , 5807 , 5813 , 5821 , 5827 , 5839 , 5843 , 5849 , // 96
5851 , 5857 , 5861 , 5867 , 5869 , 5879 , 5881 , 5897 , // 97
5903 , 5923 , 5927 , 5939 , 5953 , 5981 , 5987 , 6007 , // 98
6011 , 6029 , 6037 , 6043 , 6047 , 6053 , 6067 , 6073 , // 99
6079 , 6089 , 6091 , 6101 , 6113 , 6121 , 6131 , 6133 , // 100
6143 , 6151 , 6163 , 6173 , 6197 , 6199 , 6203 , 6211 , // 101
6217 , 6221 , 6229 , 6247 , 6257 , 6263 , 6269 , 6271 , // 102
6277 , 6287 , 6299 , 6301 , 6311 , 6317 , 6323 , 6329 , // 103
6337 , 6343 , 6353 , 6359 , 6361 , 6367 , 6373 , 6379 , // 104
6389 , 6397 , 6421 , 6427 , 6449 , 6451 , 6469 , 6473 , // 105
6481 , 6491 , 6521 , 6529 , 6547 , 6551 , 6553 , 6563 , // 106
6569 , 6571 , 6577 , 6581 , 6599 , 6607 , 6619 , 6637 , // 107
6653 , 6659 , 6661 , 6673 , 6679 , 6689 , 6691 , 6701 , // 108
6703 , 6709 , 6719 , 6733 , 6737 , 6761 , 6763 , 6779 , // 109
6781 , 6791 , 6793 , 6803 , 6823 , 6827 , 6829 , 6833 , // 110
6841 , 6857 , 6863 , 6869 , 6871 , 6883 , 6899 , 6907 , // 111
6911 , 6917 , 6947 , 6949 , 6959 , 6961 , 6967 , 6971 , // 112
6977 , 6983 , 6991 , 6997 , 7001 , 7013 , 7019 , 7027 , // 113
7039 , 7043 , 7057 , 7069 , 7079 , 7103 , 7109 , 7121 , // 114
7127 , 7129 , 7151 , 7159 , 7177 , 7187 , 7193 , 7207 , // 115
7211 , 7213 , 7219 , 7229 , 7237 , 7243 , 7247 , 7253 , // 116
7283 , 7297 , 7307 , 7309 , 7321 , 7331 , 7333 , 7349 , // 117
7351 , 7369 , 7393 , 7411 , 7417 , 7433 , 7451 , 7457 , // 118
7459 , 7477 , 7481 , 7487 , 7489 , 7499 , 7507 , 7517 , // 119
7523 , 7529 , 7537 , 7541 , 7547 , 7549 , 7559 , 7561 , // 120
7573 , 7577 , 7583 , 7589 , 7591 , 7603 , 7607 , 7621 , // 121
7639 , 7643 , 7649 , 7669 , 7673 , 7681 , 7687 , 7691 , // 122
7699 , 7703 , 7717 , 7723 , 7727 , 7741 , 7753 , 7757 , // 123
7759 , 7789 , 7793 , 7817 , 7823 , 7829 , 7841 , 7853 , // 124
7867 , 7873 , 7877 , 7879 , 7883 , 7901 , 7907 , 7919 , // 125
7927 , 7933 , 7937 , 7949 , 7951 , 7963 , 7993 , 8009 , // 126
8011 , 8017 , 8039 , 8053 , 8059 , 8069 , 8081 , 8087 , // 127
8089 , 8093 , 8101 , 8111 , 8117 , 8123 , 8147 , 8161 , // 128
8167 , 8171 , 8179 , 8191 , 8209 , 8219 , 8221 , 8231 , // 129
8233 , 8237 , 8243 , 8263 , 8269 , 8273 , 8287 , 8291 , // 130
8293 , 8297 , 8311 , 8317 , 8329 , 8353 , 8363 , 8369 , // 131
8377 , 8387 , 8389 , 8419 , 8423 , 8429 , 8431 , 8443 , // 132
8447 , 8461 , 8467 , 8501 , 8513 , 8521 , 8527 , 8537 , // 133
8539 , 8543 , 8563 , 8573 , 8581 , 8597 , 8599 , 8609 , // 134
8623 , 8627 , 8629 , 8641 , 8647 , 8663 , 8669 , 8677 , // 135
8681 , 8689 , 8693 , 8699 , 8707 , 8713 , 8719 , 8731 , // 136
8737 , 8741 , 8747 , 8753 , 8761 , 8779 , 8783 , 8803 , // 137
8807 , 8819 , 8821 , 8831 , 8837 , 8839 , 8849 , 8861 , // 138
8863 , 8867 , 8887 , 8893 , 8923 , 8929 , 8933 , 8941 , // 139
8951 , 8963 , 8969 , 8971 , 8999 , 9001 , 9007 , 9011 , // 140
9013 , 9029 , 9041 , 9043 , 9049 , 9059 , 9067 , 9091 , // 141
9103 , 9109 , 9127 , 9133 , 9137 , 9151 , 9157 , 9161 , // 142
9173 , 9181 , 9187 , 9199 , 9203 , 9209 , 9221 , 9227 , // 143
9239 , 9241 , 9257 , 9277 , 9281 , 9283 , 9293 , 9311 , // 144
9319 , 9323 , 9337 , 9341 , 9343 , 9349 , 9371 , 9377 , // 145
9391 , 9397 , 9403 , 9413 , 9419 , 9421 , 9431 , 9433 , // 146
9437 , 9439 , 9461 , 9463 , 9467 , 9473 , 9479 , 9491 , // 147
9497 , 9511 , 9521 , 9533 , 9539 , 9547 , 9551 , 9587 , // 148
9601 , 9613 , 9619 , 9623 , 9629 , 9631 , 9643 , 9649 , // 149
9661 , 9677 , 9679 , 9689 , 9697 , 9719 , 9721 , 9733 , // 150
9739 , 9743 , 9749 , 9767 , 9769 , 9781 , 9787 , 9791 , // 151
9803 , 9811 , 9817 , 9829 , 9833 , 9839 , 9851 , 9857 , // 152
9859 , 9871 , 9883 , 9887 , 9901 , 9907 , 9923 , 9929 , // 153
9931 , 9941 , 9949 , 9967 , 9973 , 10007, 10009, 10037, // 154
10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, // 155
10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, // 156
10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, // 157
10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, // 158
10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, // 159
10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, // 160
10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, // 161
10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, // 162
10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, // 163
10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, // 164
10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, // 165
10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, // 166
10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, // 167
11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, // 168
11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, // 169
11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, // 170
11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, // 171
11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, // 172
11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, // 173
11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, // 174
11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, // 175
11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, // 176
11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, // 177
11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, // 178
11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941, // 179
11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, // 180
12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, // 181
12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, // 182
12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, // 183
12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, // 184
12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, // 185
12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, // 186
12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, // 187
12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, // 188
12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, // 189
12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, // 190
12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, // 191
12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, // 192
12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, // 193
12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, // 194
13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, // 195
13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, // 196
13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, // 197
13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, // 198
13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, // 199
13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, // 200
13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, // 201
13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, // 202
13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, // 203
13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, // 204
13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, // 205
13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, // 206
13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, // 207
14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, // 208
14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, // 209
14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, // 210
14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, // 211
14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, // 212
14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, // 213
14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, // 214
14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, // 215
14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, // 216
14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, // 217
14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887, // 218
14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, // 219
14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, // 220
15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, // 221
15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, // 222
15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, // 223
15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, // 224
15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, // 225
15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, // 226
15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, // 227
15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, // 228
15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, // 229
15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, // 230
15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, // 231
15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, // 232
15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, // 233
16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, // 234
16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, // 235
16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, // 236
16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, // 237
16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, // 238
16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, // 239
16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, // 240
16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, // 241
16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, // 242
16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, // 243
16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, // 244
16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, // 245
17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, // 246
17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, // 247
17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231, // 248
17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, // 249
17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, // 250
17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, // 251
17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, // 252
17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, // 253
17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, // 254
17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, // 255
17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, // 256
17881, 17891, 17903, 17909, 17911, 17921, 17923, 17929, // 257
17939, 17957, 17959, 17971, 17977, 17981, 17987, 17989); // 258 < 18,000
{ == Local LbInteger routines ============================================= }
procedure LbBiInit(var N1 : LbInteger; Precision : Integer);
begin
FillChar(N1, SizeOf(LbInteger), $00);
if (Precision > 0) then
N1.IntBuf.dwLen := Precision
else
N1.IntBuf.dwLen := cDEFAULT_PRECISION;
N1.bSign := cDEFAULT_SIGN;
N1.dwUsed := cDEFAULT_USED;
N1.IntBuf.pBuf := pByte(AllocMem(N1.IntBuf.dwLen));
end;
{ ------------------------------------------------------------------- }
procedure LbBiRealloc(var N1 : LbInteger; Len : integer); {!!03}
var
tmpPtr : pByte;
begin
if (N1.dwUsed > Len) then
Exit;
tmpPtr := AllocMem(Len);
move(N1.IntBuf.pBuf^, tmpPtr^, N1.dwUsed);
FreeMem(N1.IntBuf.pBuf);
N1.IntBuf.dwLen := Len;
N1.IntBuf.pBuf := tmpPtr;
end;
{ ------------------------------------------------------------------- }
procedure LbBiFree(var N1 : LbInteger);
begin
if (assigned(N1.IntBuf.pBuf)) then
FreeMem(N1.IntBuf.pBuf);
FillChar(N1, SizeOf(LbInteger), $00);
end;
{ ------------------------------------------------------------------- }
procedure LbBiClear(var N1 : LbInteger);
begin
N1.bSign := cDEFAULT_SIGN;
N1.dwUsed := cDEFAULT_USED;
FillChar(N1.IntBuf.pBuf^, N1.IntBuf.dwLen, $00);
end;
{ ------------------------------------------------------------------- }
function LbBiGetByteValue (N1 : LbInteger; place : integer): byte; {!!03}
begin
if (N1.dwUsed < place) then begin
Result := 0;
exit;
end;
Result := pBiByteArray( N1.IntBuf.pBuf )[pred(place)];
end;
{ ------------------------------------------------------------------- }
procedure LbBiTrimSigZeros(var N1 : LbInteger);
begin
if (not assigned(N1.IntBuf.pBuf)) then
raise Exception.Create(sBIBufferNotAssigned);
while(pBiByteArray( N1.IntBuf.pBuf )[pred(N1.dwUsed)] = 0)do begin
dec(N1.dwUsed);
{ leave at least 1 zero }
if (N1.dwUsed <= 0) then begin
N1.dwUsed := 1;
exit;
end;
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiVerify(var N1 : LbInteger);
begin
{ check to see that pointer points at data }
if (not(assigned(N1.IntBuf.pBuf))) then
raise Exception.Create(sBIBufferNotAssigned);
{ make sure that there are some numbers }
if (N1.dwUsed = 0) then
raise Exception.Create(sBINoNumber);
LbBiTrimSigZeros(N1);
end;
{ ------------------------------------------------------------------- }
procedure LbBiFindLargestUsed(N1 : LbInteger; N2 : LbInteger; var count : integer); {!!03}
begin
if (N1.dwUsed >= N2.dwUsed) then
Count := N1.dwUsed
else
Count := N2.dwUsed;
end;
{ ------------------------------------------------------------------- }
function LbBiFindFactor(B1 : byte) : byte;
begin
Result := 1;
while(B1 < $80)do begin
B1 := (B1 shl 1);
Result := Result * 2;
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiPrepare(N1 : LbInteger; N2 : LbInteger;
var N3 : LbInteger);
begin
{ if pointer does not point at data then we make some }
if (not(assigned(N3.IntBuf.pBuf))) then
LbBiRealloc(N3, cDEFAULT_PRECISION);
fillchar(N3.IntBuf.pBuf^, N3.IntBuf.dwLen, $00);
N3.dwUsed := cDEFAULT_USED;
end;
{ ------------------------------------------------------------------- }
procedure LbBiCopy(var dest : LbInteger; src : LbInteger; len : Integer);
var
ptr : pByte;
size : integer; {!!03}
begin
fillchar(dest.IntBuf.pBuf^, dest.IntBuf.dwLen, $00);
size := integer(len); {!!03}
if size > dest.IntBuf.dwLen then
LbBiRealloc(dest, size);
ptr := dest.IntBuf.pBuf;
move(src.IntBuf.pBuf^, ptr^, len);
if (dest.dwUsed < size) then
dest.dwUsed := size;
end;
{ ------------------------------------------------------------------- }
function LbBiGetBit(N1 : LbInteger; bit : Integer) : Boolean;
var
tmp : Integer;
mask : byte;
begin
mask := $01;
mask := mask shl (bit mod 8);
tmp := (bit div 8) + 1 ;
tmp := LbBiGetByteValue(N1, tmp);
Result := ((mask and tmp) = mask);
end;
{ ------------------------------------------------------------------- }
procedure LbBiAddByte(var N1 : LbInteger; place : integer; _byte : byte); {!!03}
begin
if (place = cAPPEND_ARRAY) then begin
if (succ(N1.dwUsed) > N1.IntBuf.dwLen) then
LbBiRealloc(N1, succ(N1.dwUsed));
pBiByteArray( N1.IntBuf.pBuf )[N1.dwUsed] := _byte;
inc(N1.dwUsed);
end else begin
if (place > N1.IntBuf.dwLen) then
LbBiRealloc(N1, place);
pBiByteArray(N1.IntBuf.pBuf)[pred(place)] := _byte;
if (N1.dwUsed < place) then
N1.dwUsed := place;
end;
end;
{ ------------------------------------------------------------------- }
function LbBiCompare(N1 : LbInteger; N2 : LbInteger): Shortint;
var
cnt : Integer;
begin
LbBiTrimSigZeros( N1 );
LbBiTrimSigZeros( N2 );
if (N1.bSign <> N2.bSign) then begin
if (N1.bSign = cPOSITIVE) then
Result := cGREATER_THAN
else
Result := cLESS_THAN;
exit;
end;
if (N1.dwUsed <> N2.dwUsed) then begin
if (N1.dwUsed > N2.dwUsed) then begin
Result := cGREATER_THAN;
exit;
end else begin
Result := cLESS_THAN;
exit;
end;
end;
cnt := N1.dwUsed;
while pBiByteArray( N1.IntBuf.pBuf )[pred(cnt)] =
pBiByteArray( N2.IntBuf.pBuf )[pred(cnt)] do begin
dec(cnt);
if (cnt = 0) then begin
Result := cEQUAL_TO;
exit;
end;
end;
if pBiByteArray( N1.IntBuf.pBuf )[pred(cnt)] >
pBiByteArray( N2.IntBuf.pBuf )[pred(cnt)] then
Result := cGREATER_THAN
else
Result := cLESS_THAN;
end;
{ ------------------------------------------------------------------- }
function LbBiAbs(N1 : LbInteger; N2 : LbInteger): Shortint;
var
cnt : Integer;
begin
LbBiTrimSigZeros(N1);
LbBiTrimSigZeros(N2);
if (N1.dwUsed <> N2.dwUsed) then begin
if (N1.dwUsed > N2.dwUsed) then begin
Result := cGREATER_THAN;
exit;
end else begin
Result := cLESS_THAN;
exit;
end;
end;
cnt := N1.dwUsed;
while pBiByteArray( N1.IntBuf.pBuf )[pred(cnt)] =
pBiByteArray( N2.IntBuf.pBuf )[pred(cnt)] do begin
dec(cnt);
if (cnt = 0) then begin
Result := cEQUAL_TO;
exit;
end;
end;
if pBiByteArray( N1.IntBuf.pBuf )[pred(cnt)] >
pBiByteArray( N2.IntBuf.pBuf )[pred(cnt)] then
Result := cGREATER_THAN
else
Result := cLESS_THAN;
end;
{ ------------------------------------------------------------------- }
function LbBiIsZero(N1 : LbInteger) : Boolean;
begin
LbBiTrimSigZeros( N1 );
Result := False;
if (N1.dwUsed = 1) and (pBiByteArray( N1.IntBuf.pBuf )[0] = 0) then
Result := True
end;
{ ------------------------------------------------------------------- }
function LbBiIsOne(N1 : LbInteger) : Boolean;
begin
LbBiTrimSigZeros( N1 );
Result := False;
if (N1.dwUsed = 1) and (pBiByteArray( N1.IntBuf.pBuf )[0] = 1) then
Result := True
end;
{ ------------------------------------------------------------------- }
function LbBiIsOdd(N1 : LbInteger): Boolean;
begin
Result := odd(LbBiGetByteValue(N1, 1));
end;
{ ------------------------------------------------------------------- }
function LbBiIsEven(N1 : LbInteger): Boolean;
begin
Result := not (odd(LbBiGetByteValue(N1, 1)));
end;
{ ------------------------------------------------------------------- }
procedure LbBiSwap(var N1 : LbInteger; var N2 : LbInteger);
var
tmp : LbInteger;
begin
tmp.bSign := N1.bSign; {!!.01}
tmp.dwUsed := N1.dwUsed; {!!.01}
tmp.IntBuf.dwLen := N1.IntBuf.dwLen; {!!.01}
tmp.IntBuf.pBuf := N1.IntBuf.pBuf; {!!.01}
N1.bSign := N2.bSign; {!!.01}
N1.dwUsed := N2.dwUsed; {!!.01}
N1.IntBuf.dwLen := N2.IntBuf.dwLen; {!!.01}
N1.IntBuf.pBuf := N2.IntBuf.pBuf; {!!.01}
N2.bSign := tmp.bSign; {!!.01}
N2.dwUsed := tmp.dwUsed; {!!.01}
N2.IntBuf.dwLen := tmp.IntBuf.dwLen; {!!.01}
N2.IntBuf.pBuf := tmp.IntBuf.pBuf; {!!.01}
end;
{ ------------------------------------------------------------------- }
function LbBiReverseBits(byt : Byte) : Byte;
var
i : byte;
rBit : Byte;
begin
Result := 0;
rBit := $80;
for i := 1 to 8 do begin
if ((byt and $01) <> 0) then
Result := Result or rBit;
rBit := rBit shr 1;
byt := byt shr 1;
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiShr(var N1 : LbInteger; _shr : Integer);
var
bitShr : byte;
byteShr : Integer;
carry : byte;
tmp : word;
shifted : byte;
i : Integer;
t : LbInteger;
begin
if _shr < 1 then exit; {!!.01}
LbBiVerify(N1);
LbBiInit(t, cDEFAULT_PRECISION);
LbBiAddByte(t, cPREPEND_ARRAY, $00);
byteShr := _shr div 8;
bitShr := _shr mod 8;
if( byteShr > integer( N1.dwUsed ))then begin
LbBiClear( N1 );
LbBiAddByte( N1, cPREPEND_ARRAY, $00 );
end;
carry := 0;
try
for i := N1.dwUsed downto 1 do begin
if (i - byteShr) < 1 then break;
tmp := pBiByteArray( N1.IntBuf.pBuf )[pred(i)];
shifted := (tmp shr bitShr) or carry;
LbBiAddByte(t, i - byteShr, byte(shifted and $00FF));
carry := ((tmp shl (8 - bitShr)) and $00FF);
end;
LbBiCopy(N1, t, t.dwUsed);
finally
LbBiTrimSigZeros( N1 );
LbBiFree(t);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiShl(var N1 : LbInteger; _shl : Integer);
var
bitShl : byte;
byteShl : Integer;
tmp : word;
shifted : byte;
carry : byte;
t : LbInteger;
i : Integer;
x : Integer;
begin
if _shl < 1 then exit; {!!.01}
LbBiVerify(N1);
LbBiInit(t, cDEFAULT_PRECISION);
LbBiAddByte(t, cPREPEND_ARRAY, $00);
byteShl := _shl div 8;
bitShl := _shl mod 8;
try
carry := 0;
x := 0;
for i := 1 to N1.dwUsed do begin
tmp := pBiByteArray( N1.IntBuf.pBuf )[pred(i)];
shifted := ((tmp shl bitShl) and $00FF) or carry;
LbBiAddByte(t, i + byteShl, byte(shifted and $00FF));
carry := ((tmp shr (8 - bitShl)) and $00FF);
x := i;
end;
LbBiAddByte(t, succ(x) + byteShl, carry);
LbBiCopy(N1, t, t.dwUsed);
finally
LbBiTrimSigZeros(N1);
LbBiFree(t);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiOR(N1 : LbInteger; N2 : LbInteger; var NOR : LbInteger);
var
count : integer; {!!03}
i : integer; {!!03}
a : byte;
b : byte;
begin
LbBiVerify(N1);
LbBiVerify(N2);
LbBiPrepare(N1, N2, NOR);
LbBiAddByte(NOR, cPREPEND_ARRAY, $00);
LbBiFindLargestUsed(N1, N2, count);
for i := 1 to count do begin
a := LbBiGetByteValue(N1, i);
b := LbBiGetByteValue(N2, i);
a := a or b;
LbBiAddByte(NOR, i, a);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiORInPlace(var N1 : LbInteger; N2 : LbInteger);
var
Nor : LbInteger;
prec : Integer;
begin
if (N1.dwUsed > N2.dwUsed) then prec := succ(N1.dwUsed)
else prec := succ(N2.dwUsed);
LbBiInit(Nor, prec);
try
LbBiOR(N1, N2, Nor);
LbBiClear(N1);
N1.dwUsed := Nor.dwUsed;
N1.bSign := Nor.bSign;
if (N1.IntBuf.dwLen < Nor.IntBuf.dwLen) then
LbBiRealloc(N1, Nor.IntBuf.dwLen);
LbBiCopy(N1 , Nor, Nor.dwUsed);
finally
LbBiFree(Nor);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiXOR(N1 : LbInteger; N2 : LbInteger; var NXOR : LbInteger);
var
count : integer; {!!03}
i : integer; {!!03}
a : byte;
b : byte;
begin
LbBiVerify(N1);
LbBiVerify(N2);
LbBiPrepare(N1, N2, NXOR);
LbBiAddByte(NXOR, cPREPEND_ARRAY, $00);
LbBiFindLargestUsed(N1, N2, count);
for i := 1 to count do begin
a := LbBiGetByteValue(N1, i);
b := LbBiGetByteValue(N2, i);
a := a xor b;
LbBiAddByte(NXOR, i, a);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiXORInPlace(var N1 : LbInteger; N2 : LbInteger);
var
Nxor : LbInteger;
prec : Integer;
begin
if (N1.dwUsed > N2.dwUsed) then prec := succ(N1.dwUsed)
else prec := succ(N2.dwUsed);
LbBiInit(Nxor, prec);
try
LbBiXOR(N1, N2, Nxor);
LbBiClear(N1);
N1.dwUsed := Nxor.dwUsed;
N1.bSign := Nxor.bSign;
if (N1.IntBuf.dwLen < Nxor.IntBuf.dwLen) then
LbBiRealloc(N1, Nxor.IntBuf.dwLen);
LbBiCopy(N1 , Nxor, Nxor.dwUsed);
finally
LbBiFree(Nxor);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiMove(var dest : LbInteger; src : LbInteger;
place : integer; len : Integer); {!!03}
var
ptr : pByte;
size : integer; {!!03}
begin
if (not assigned(dest.IntBuf.pBuf)) then
raise Exception.Create(sBIBufferNotAssigned);
if (place = cAPPEND_ARRAY) then begin
if ((integer(len) + dest.dwUsed) > dest.IntBuf.dwLen) then {!!03}
LbBiRealloc(dest, (integer(len) + dest.dwUsed)); {!!03}
ptr := dest.IntBuf.pBuf;
inc(ptr, dest.dwUsed);
move(src.IntBuf.pBuf^, ptr^, len);
inc(dest.dwUsed, len);
end else begin
size := pred(place) + integer(len); {!!03}
if size > dest.IntBuf.dwLen then
LbBiRealloc(dest, size);
ptr := dest.IntBuf.pBuf;
inc(ptr, pred(place));
move(src.IntBuf.pBuf^, ptr^, len);
if (dest.dwUsed < size) then
dest.dwUsed := size;
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiAddBase(N1 : LbInteger; N2 : LbInteger; var Sum : LbInteger);
var
Carry : byte;
cnt : Integer;
Count : integer; {!!03}
tmp_wrd : WORD;
tmp_byt : byte;
begin
LbBiFindLargestUsed(N1, N2, Count);
if( LbBiIsZero( N1 ))then begin
LbBiCopy(sum, N2, N2.dwUsed);
exit;
end;
if( LbBiIsZero( N2 ))then begin
LbBiCopy(sum, N1, N1.dwUsed);
exit;
end;
Carry := 0;
if (succ(count) > Sum.dwUsed) then
LbBiRealloc(Sum, succ(count));
{ add digits }
for cnt := 1 to count do begin
tmp_wrd := LbBiGetByteValue(N1, cnt) +
LbBiGetByteValue(N2, cnt) + Carry;
tmp_byt := tmp_wrd and $00FF;
Carry := tmp_wrd shr 8;
pBiByteArray(Sum.IntBuf.pBuf )[Sum.dwUsed] := tmp_byt;
inc(Sum.dwUsed);
end;
{ finish by adding the carry }
LbBiAddByte(Sum, cAPPEND_ARRAY, Carry);
{ trim off any significant zeros }
LbBiTrimSigZeros(Sum);
end;
{ ------------------------------------------------------------------- }
procedure LbBiSubBase(N1 : LbInteger; N2 : LbInteger;
var Diff : LbInteger);
var
tmp : integer;
Borrow : WORD;
cnt : integer; {!!03}
x : integer; {!!03}
begin
if( LbBiIsZero( N1 ))then begin
LbBiCopy(Diff, N2, N2.dwUsed);
exit;
end;
if( LbBiIsZero( N2 ))then begin
LbBiCopy(Diff, N1, N1.dwUsed);
exit;
end;
Borrow := 0;
x := pred(N1.dwUsed);
for cnt := 0 to x do begin
tmp := pBiByteArray(N1.IntBuf.pBuf)[cnt];
if (N2.dwUsed < succ(cnt)) then
tmp := tmp - Borrow
else
tmp := tmp - (pBiByteArray(N2.IntBuf.pBuf)[cnt] + Borrow);
if (tmp < 0) then begin
inc(tmp, cBYTE_POSSIBLE_VALUES);
Borrow := 1;
end else
Borrow := 0;
if (succ(Diff.dwUsed) > Diff.IntBuf.dwLen) then
LbBiRealloc(Diff, succ(Diff.dwUsed));
pBiByteArray(Diff.IntBuf.pBuf )[Diff.dwUsed] := tmp;
inc(Diff.dwUsed);
end;
if (Borrow <> 0) then
raise Exception.Create(sBISubtractErr);
{ trim off any significant zeros }
LbBiTrimSigZeros(Diff);
end;
{ ------------------------------------------------------------------- }
procedure LbBiAdd(N1 : LbInteger; N2 : LbInteger; var Sum : LbInteger);
var
value : Shortint;
begin
if (N1.bSign = N2.bSign) then begin
Sum.bSign := N1.bSign;
LbBiAddBase(N1, N2, Sum);
end else begin
value := LbBiAbs(N1, N2);
if (value = cEQUAL_TO) then begin
LbBiAddByte(Sum, cPREPEND_ARRAY, $00);
exit;
end else if (value = cGREATER_THAN) then begin
Sum.bSign := N1.bSign;
LbBiSubBase(N1, N2, Sum);
end else begin
Sum.bSign := N2.bSign;
LbBiSubBase(N2, N1, Sum);
end;
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiSub(N1 : LbInteger; N2 : LbInteger; var diff : LbInteger);
begin
N2.bSign := not N2.bSign;
LbBiAdd(N1, N2, diff);
end;
{ ------------------------------------------------------------------- }
procedure LbBiAddInPlace(var N1 : LbInteger; N2 : LbInteger);
var
sum : LbInteger;
prec : Integer;
begin
if (N1.dwUsed > N2.dwUsed) then
prec := succ(N1.dwUsed)
else
prec := succ(N2.dwUsed);
LbBiInit(sum, prec);
try
LbBiAdd(N1, N2, sum);
LbBiClear(N1);
N1.dwUsed := sum.dwUsed;
N1.bSign := sum.bSign;
if (N1.IntBuf.dwLen < sum.IntBuf.dwLen) then
LbBiRealloc(N1, sum.IntBuf.dwLen);
LbBiCopy(N1 , sum, sum.dwUsed);
finally
LbBiFree(sum);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiSubInPlace(var N1 : LbInteger; N2 : LbInteger);
var
Difference : LbInteger;
prec : Integer;
begin
if (N1.dwUsed > N2.dwUsed) then
prec := succ(N1.dwUsed)
else
prec := succ(N2.dwUsed);
LbBiInit(Difference, prec);
try
LbBiSub(N1, N2, Difference);
LbBiClear(N1);
N1.dwUsed := Difference.dwUsed;
N1.bSign := Difference.bSign;
if (N1.IntBuf.dwLen < Difference.IntBuf.dwLen) then
LbBiRealloc(N1, Difference.IntBuf.dwLen);
LbBiCopy(N1, Difference, Difference.dwUsed);
finally
LbBiFree(Difference);
end;
end;
{ ------------------------------------------------------------------- }
function MultSpecialCase(N1 : LbInteger; N2 : LbInteger;
var Product : LbInteger) : Boolean;
begin
Result := False;
{ if either one is zero then the product is zero }
if (LbBiIsZero(N1) or LbBiIsZero(N2)) then begin
LbBiAddByte(Product, cPREPEND_ARRAY, $00);
Result := True;
exit;
end;
{ if N1 := 1 }
if (LbBiIsOne(N1)) then begin
product.dwUsed := N2.dwUsed;
if (product.IntBuf.dwLen < N2.IntBuf.dwLen) then
LbBiRealloc(product, N2.IntBuf.dwLen);
LbBiCopy(product, N2, N2.dwUsed);
Result := True;
exit;
end;
{ if N2 := 1 }
if (LbBiIsOne(N2)) then begin
product.dwUsed := N1.dwUsed;
if (product.IntBuf.dwLen < N1.IntBuf.dwLen) then
LbBiRealloc(product, N1.IntBuf.dwLen);
LbBiCopy(product, N1, N1.dwUsed);
Result := True;
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiMultBase(N1 : LbInteger; N2 : LbInteger;
var Product : LbInteger);
var
InxX : integer; {!!03}
InxY : integer; {!!03}
MaxX : integer; {!!03}
Carry : integer; {!!03}
prd : integer; {!!03}
plc : integer; {!!03}
byt : byte;
tmp : integer; {!!03}
begin
if (MultSpecialCase(N1, N2, Product)) then
exit;
MaxX := pred(N1.dwUsed);
tmp := pred(N2.dwUsed);
for InxY := 0 to tmp do begin
if pBiByteArray(N2.IntBuf.pBuf)[InxY] <> 0 then begin
Carry := 0;
for InxX := 0 to MaxX do begin
plc := InxX + InxY;
prd := pBiByteArray(N1.IntBuf.pBuf)[InxX];
prd := prd * pBiByteArray(N2.IntBuf.pBuf)[InxY];
if (Product.dwUsed < plc) then
prd := prd + Carry
else
prd := prd + pBiByteArray(Product.IntBuf.pBuf)[plc] + Carry;
byt := prd and $00FF;
Carry := prd shr 8;
if (succ(plc) > Product.IntBuf.dwLen) then
LbBiRealloc(Product, plc + 100);
pBiByteArray(Product.IntBuf.pBuf )[plc] := byt;
if (Product.dwUsed < succ(plc)) then
N1.dwUsed := succ(plc);
end;
LbBiAddByte(Product, (MaxX + InxY + 2), Carry);
end;
end;
{ trim off any significant zeros }
LbBiTrimSigZeros(Product);
end;
{ ------------------------------------------------------------------- }
procedure LbBiMult(N1 : LbInteger; N2 : LbInteger;
var Product : LbInteger);
begin
LbBiMultBase(N1, N2, Product);
if (N1.bSign = N2.bSign) then
Product.bSign := cPOSITIVE
else
Product.bSign := cNEGATIVE;
end;
{ ------------------------------------------------------------------- }
procedure LbBiMultInPlace(var N1 : LbInteger; N2 : LbInteger);
var
product : LbInteger;
precis : Integer;
begin
precis := (N1.dwUsed + N2.dwUsed) * 2;
LbBiInit(product, precis);
LbBiMult(N1, N2, product);
LbBiClear(N1);
N1.dwUsed := product.dwUsed;
N1.bSign := product.bSign;
if (N1.IntBuf.dwLen < product.IntBuf.dwLen) then
LbBiRealloc(N1, product.IntBuf.dwLen);
LbBiCopy(N1, product, product.dwUsed);
LbBiFree(product);
end;
{ ------------------------------------------------------------------- }
procedure LbBiMulByDigitBase(N1 : LbInteger; N2 : byte;
var product : LbInteger);
var
cnt : integer; {!!03}
carry : byte;
prd : WORD;
byt : byte;
tmp : integer; {!!03}
begin
if (N2 = 1) then begin
if (product.IntBuf.dwLen < N1.IntBuf.dwLen) then
LbBiRealloc(product, N1.IntBuf.dwLen);
product.dwUsed := N1.dwUsed;
product.bSign := N1.bSign;
LbBiCopy(product, N1, N1.dwUsed);
end;
if (n2 = 0) then begin
product.dwUsed := 1;
LbBiAddByte(product, cPREPEND_ARRAY, 0);
end;
if LbBiIsOne( N1 ) then begin
product.dwUsed := 1;
LbBiAddByte(product, cPREPEND_ARRAY, N2);
end;
{ we can do this here since LbBiIsOne() did the clean up on N1 }
if (N1.dwUsed = 1) and (pBiByteArray( N1.IntBuf.pBuf )[0] = 0) then begin {!!.01}
product.dwUsed := 1;
LbBiAddByte(product, cPREPEND_ARRAY, 0);
end;
Carry := 0;
tmp := pred( N1.dwUsed );
for cnt := 0 to tmp do begin
prd := (pBiByteArray( N1.IntBuf.pBuf )[cnt] * N2) + Carry;
byt := prd and $00FF;
Carry := prd shr 8;
pBiByteArray(Product.IntBuf.pBuf )[cnt] := byt;
if (Product.dwUsed < succ(cnt)) then
N1.dwUsed := succ(cnt);
end;
LbBiAddByte(Product, succ(N1.dwUsed), Carry);
LbBiTrimSigZeros(Product);
end;
{ ------------------------------------------------------------------- }
procedure LbBiMulByDigit(N1 : LbInteger; N2 : byte;
var product : LbInteger);
begin
LbBiMulByDigitBase(N1, N2, product);
product.bSign := N1.bSign;
end;
{ ------------------------------------------------------------------- }
procedure LbBiMulByDigitInPlace(var N1 : LbInteger; N2 : byte);
var
product : LbInteger;
precis : Integer;
begin
precis := (N1.dwUsed + 1) * 2;
LbBiInit(product, precis);
try
LbBiMulByDigit(N1, N2, product);
if (N1.IntBuf.dwLen < product.IntBuf.dwLen) then
LbBiRealloc(N1, product.IntBuf.dwLen);
N1.bSign := product.bSign;
N1.dwUsed := product.dwUsed;
LbBiCopy(N1, product, product.dwUsed);
finally
LbBiFree(product);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiDivByDigitBase(N1 : LbInteger; N2 : byte;
var quotient : LbInteger;
var remainder : byte);
var
factor : byte;
c : Integer;
tmp : Integer;
sigDivd : longint;
lclQT : longint;
Carry : WORD;
plc : integer; {!!03}
lclDVD : LbInteger;
divisor : byte;
begin
LbBiInit(lclDVD, N1.dwUsed);
Carry := 0;
try
if (LbBiIsZero(N1)) then begin
LbBiAddByte(quotient, cPREPEND_ARRAY, $00);
exit;
end;
if (N2 = 1) then begin
LbBiCopy(quotient, N1, N1.dwUsed);
exit;
end;
if (N2 = 0) then
raise Exception.Create(sBIZeroDivide);
LbBiCopy(lclDVD, N1, N1.dwUsed);
divisor := N2;
{ Find the factor to increase the Significant byte greater than $80 }
factor := LbBiFindFactor(N2);
if (factor <> 1) then begin
LbBiMulByDigitInPlace(lclDVD, factor);
divisor := divisor * factor;
end;
if pBiByteArray( lclDVD.IntBuf.pBuf )[pred(lclDVD.dwUsed)] >= divisor then begin
LbBiAddByte(lclDVD, cAPPEND_ARRAY, $00);
end;
LbBiClear(quotient);
remainder := 0;
plc := pred(lclDVD.dwUsed);
if (lclDVD.dwUsed > quotient.dwUsed) then
LbBiRealloc(quotient, lclDVD.dwUsed);
Carry := 0;
tmp := pred(lclDVD.dwUsed);
for c := tmp downto 0 do begin
sigDivd := (Carry shl 8) or (integer(pBiByteArray(lclDVD.IntBuf.pBuf)[c])); {!!03}
if (SigDivd < divisor) then begin
Carry := SigDivd;
dec(plc);
continue;
end;
lclQT := sigDivd div divisor;
if (lclQT <> 0) then begin
if (lclQT >= cBYTE_POSSIBLE_VALUES) then
lclQT := pred(cBYTE_POSSIBLE_VALUES);
while sigDivd < (divisor * lclQT)do begin
dec(lclQT);
if (lclQT = 0) then
raise Exception.Create(sBIQuotientErr);
end;
end;
if (lclQT <> 0) then begin
pBiByteArray(quotient.IntBuf.pBuf )[plc] := lclQT;
if (quotient.dwUsed < succ(plc)) then
quotient.dwUsed := succ(plc);
Carry := sigDivd - (divisor * lclQT);
end;
dec(plc);
end;
finally
remainder := Carry;
if (quotient.dwUsed = 0) then
LbBiAddByte(quotient, cPREPEND_ARRAY, $00);
LbBiFree(lclDVD);
LbBiTrimSigZeros(quotient);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiDivByDigit(N1 : LbInteger; N2 : byte;
var quotient : LbInteger;
var remainder : byte);
begin
LbBiDivByDigitBase(N1, N2, quotient, remainder);
quotient.bSign := N1.bSign;
end;
{ ------------------------------------------------------------------- }
procedure LbBiDivByDigitInPlace(var N1 : LbInteger;
N2 : byte;
var remainder : byte);
var
tmp : LbInteger;
precis : Integer;
begin
precis := (N1.dwUsed + 1) * 2;
LbBiInit(tmp, precis);
try
LbBiDivByDigit(N1, N2, tmp, remainder);
N1.dwUsed := tmp.dwUsed;
N1.bSign := tmp.bSign;
if (N1.IntBuf.dwLen < tmp.IntBuf.dwLen) then
LbBiRealloc(N1, tmp.IntBuf.dwLen);
LbBiCopy(N1, tmp, tmp.dwUsed);
finally
LbBiFree(tmp);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiDivBase(N1 : LbInteger; N2 : LbInteger;
var quotient : LbInteger;
var remainder : LbInteger);
var
factor : byte;
InxQ : Integer;
InxX : Integer;
tmpByte : byte;
tmpInt : integer;
sigDigit : byte;
lclQT : longint;
lclDVD : LbInteger;
lclDSR : LbInteger;
tmpDR : LbInteger;
tmpBN : LbInteger;
sigDivd : longint;
begin
LbBiInit(lclDVD, N1.dwUsed);
LbBiInit(lclDSR, N1.dwUsed);
LbBiInit(tmpDR, N1.dwUsed);
LbBiInit(tmpBN, N1.dwUsed);
try
{ Should move special cases to a seperate procedure }
if (N1.dwUsed < 1)or
(N2.dwUsed < 1) then
raise Exception.Create(sBINoNumber);
if LbBiIsZero( N1 )then begin
LbBiAddByte(quotient , cPREPEND_ARRAY, $00);
LbBiAddByte(remainder, cPREPEND_ARRAY, $00);
exit;
end;
if LbBiIsOne( N2 )then begin
LbBiCopy(quotient, N1, N1.dwUsed);
LbBiAddByte(remainder, cPREPEND_ARRAY, $00);
exit;
end;
if LbBiIsZero( N2 )then
raise Exception.Create(sBIZeroDivide);
{ since only the pointer is saved and not the memory pointed at we }
{ need to move it over to preserve the numbers }
LbBiCopy(lclDVD, N1, N1.dwUsed);
LbBiCopy(lclDSR, N2, N2.dwUsed);
{ Find the factor to increase the Significant byte greater than $80 }
LbBiTrimSigZeros(lclDSR);
tmpByte := pBiByteArray(lclDSR.IntBuf.pBuf)[pred(lclDSR.dwUsed)];
if (tmpByte = 0) then
raise Exception.Create(sBIZeroFactor);
factor := LbBiFindFactor(tmpByte);
if (factor <> 1) then begin
LbBiMulByDigitInPlace(lclDVD, factor);
LbBiMulByDigitInPlace(lclDSR, factor);
end;
{***************************************************************************
{* if the most sigDigit of the dividend is greater than or
{* equal to that of the divisor, increment the number of
{* digits in the dividend;
{**************************************************************************}
if pBiByteArray(lclDVD.IntBuf.pBuf)[pred(lclDVD.dwUsed)] >=
pBiByteArray(lclDSR.IntBuf.pBuf)[pred(lclDSR.dwUsed)] then begin
LbBiAddByte(lclDVD, cAPPEND_ARRAY, $00);
end;
while(lclDVD.dwUsed < lclDSR.dwUsed)do
LbBiAddByte(lclDVD, cAPPEND_ARRAY, $00);
InxQ := lclDVD.dwUsed - lclDSR.dwUsed + 1;
InxX := lclDVD.dwUsed;
LbBiClear(quotient);
LbBiClear(remainder);
sigDigit := pBiByteArray(lclDSR.IntBuf.pBuf)[pred(lclDSR.dwUsed)];
if (sigDigit = 0) then begin
tmpInt := pred(lclDSR.dwUsed);
while sigDigit = 0 do begin
sigDigit := pBiByteArray(lclDSR.IntBuf.pBuf)[tmpInt];
dec(tmpInt);
if tmpInt < 0 then
raise Exception.Create(sBIQuotientErr);
end;
end;
while InxQ >= 1 do begin
if (lclDVD.dwUsed = 1) then
sigDivd := pBiByteArray(lclDVD.IntBuf.pBuf)[0]
else
sigDivd := integer(pBiByteArray(lclDVD.IntBuf.pBuf)[InxX]) {!!03}
shl 8 + pBiByteArray(lclDVD.IntBuf.pBuf)[pred(InxX)];
lclQT := sigDivd div sigDigit;
if (lclQT <> 0) then begin
if (lclQT >= cBYTE_POSSIBLE_VALUES) then
lclQT := pred(cBYTE_POSSIBLE_VALUES);
LbBiClear(tmpDR);
LbBiMove(tmpDR, lclDSR, InxQ, lclDSR.dwUsed);
LbBiMulByDigitInPlace(tmpDR, lclQT);
while(LbBiCompare(lclDVD, tmpDR) = cLESS_THAN)do begin
dec(lclQT);
if (lclQT = 0) then break;
LbBiClear(tmpDR);
LbBiMove(tmpDR, lclDSR, InxQ, lclDSR.dwUsed);
LbBiMulByDigitInPlace(tmpDR, lclQT);
end;
end;
if (lclQT <> 0) then begin
LbBiAddByte(quotient, InxQ , lclQT);
LbBiSubInPlace (lclDVD, tmpDR);
end;
dec(InxX);
dec(InxQ);
end;
LbBiCopy(remainder, lclDVD, lclDVD.dwUsed);
if (factor <> 0) then begin
if (remainder.dwUsed > 1) then begin
LbBiDivByDigitInPlace(remainder, factor, tmpByte);
end else if (remainder.dwUsed = 1) then begin
tmpByte := pBiByteArray(remainder.IntBuf.pBuf)[0];
tmpByte := tmpByte div factor;
LbBiAddByte(remainder, cPREPEND_ARRAY, tmpByte);
end;
end;
finally
LbBiFree(lclDVD);
LbBiFree(lclDSR);
LbBiFree(tmpDR);
LbBiFree(tmpBN);
if (quotient.dwUsed = 0) then
LbBiAddByte(quotient, cPREPEND_ARRAY, $00);
if (remainder.dwUsed = 0) then begin
LbBiAddByte(remainder, cPREPEND_ARRAY, $00);
end;
LbBiTrimSigZeros(quotient);
LbBiTrimSigZeros(remainder);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiDiv(N1 : LbInteger; N2 : LbInteger;
var quotient : LbInteger;
var remainder : LbInteger);
begin
LbBiDivBase(N1, N2, quotient, remainder);
if (N1.bSign = N2.bSign) then
quotient.bSign := cPOSITIVE
else
quotient.bSign := cNEGATIVE;
end;
{ ------------------------------------------------------------------- }
procedure LbBiDivInPlace(var N1 : LbInteger;
N2 : LbInteger;
var remainder : LbInteger);
var
quotient : LbInteger;
begin
LbBiInit(quotient, N1.dwUsed);
try
LbBiDiv(N1, N2, quotient, remainder);
LbBiClear(N1);
N1.dwUsed := quotient.dwUsed;
N1.bSign := quotient.bSign;
if (N1.IntBuf.dwLen < quotient.IntBuf.dwLen) then
LbBiRealloc(N1, quotient.IntBuf.dwLen);
LbBiCopy(N1, quotient, quotient.dwUsed);
finally
LbBiFree(quotient);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiMod(N1 : LbInteger; N2 : LbInteger; var remainder : LbInteger);
var
quotient : LbInteger;
begin
LbBiInit(quotient, N2.dwUsed);
LbBiDiv(N1, N2, quotient, remainder);
LbBiFree(quotient);
end;
{ ------------------------------------------------------------------- }
procedure LbBiModInPlace(var N1 : LbInteger; Modulas : LbInteger);
var
remainder : LbInteger;
begin
LbBiInit(remainder, Modulas.dwUsed);
LbBiMod(N1, Modulas, remainder);
LbBiClear(N1);
N1.dwUsed := remainder.dwUsed;
N1.bSign := remainder.bSign;
if (N1.IntBuf.dwLen < remainder.IntBuf.dwLen) then
LbBiRealloc(N1, remainder.IntBuf.dwLen);
LbBiCopy(N1, remainder, remainder.dwUsed);
LbBiFree(remainder);
end;
{ ------------------------------------------------------------------- }
procedure LbBiPowerAndMod(I1 : LbInteger;
exponent : LbInteger;
modulus : LbInteger;
var _Result : LbInteger);
var
BitCount : Integer;
i : Integer;
tmp_byte : byte;
hold : LbInteger;
begin
LbBiClear(_Result);
if (LbBiIsZero(exponent)) then begin
LbBiAddByte(_Result , cPREPEND_ARRAY, $01);
exit;
end;
LbBiInit (hold, cDEFAULT_PRECISION);
try
i := exponent.dwUsed;
LbBiAddByte(_Result , cPREPEND_ARRAY, $01);
while i > 0 do begin
tmp_byte := LbBiGetByteValue(exponent, i);
dec(i);
Bitcount := 8;
tmp_byte := LbBiReverseBits(tmp_byte);
while bitcount > 0 do begin
{r = r^2 mod m }
LbBiMultInPlace(_Result, _Result);
LbBiModInPlace(_Result, modulus);
if Odd(tmp_byte) then begin
{ r = (r * n) mod m }
LbBiMultInPlace(_Result, I1);
LbBiModInPlace(_Result, modulus);
end;
tmp_byte := tmp_byte shr 1;
dec(Bitcount);
end;
end;
finally
LbBiFree(hold);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiPowerAndModInPLace(var I1 : LbInteger;
exponent : LbInteger;
modulus : LbInteger);
var
_Result : LbInteger;
begin
LbBiInit(_Result, cUSE_DEFAULT_PRECISION);
try
LbBiPowerAndMod(I1, exponent, modulus, _Result);
LbBiClear(I1);
I1.dwUsed := _Result.dwUsed;
I1.bSign := _Result.bSign;
if (I1.IntBuf.dwLen < _Result.IntBuf.dwLen) then
LbBiRealloc(I1, _Result.IntBuf.dwLen);
LbBiCopy(I1, _Result, _Result.dwUsed);
finally
LbBiFree(_Result);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiAddByDigit(N1 : LbInteger; N2 : byte; var Sum : LbInteger);
var
tmp : LbInteger;
begin
LbBiInit(tmp, N1.dwUsed);
try
LbBiAddByte(tmp, cPREPEND_ARRAY, N2);
LbBiAdd(N1, tmp, sum);
finally
LbBiFree(tmp);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiSubByDigit(N1 : LbInteger; N2 : byte; var Sum : LbInteger);
var
tmp : LbInteger;
begin
LbBiInit(tmp, N1.dwUsed);
try
LbBiAddByte(tmp, cPREPEND_ARRAY, N2);
LbBiSub(N1, tmp, sum);
finally
LbBiFree(tmp);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiAddByDigitInPlace(var N1 : LbInteger; N2 : byte);
var
sum : LbInteger;
begin
LbBiInit(sum, N1.dwUsed);
try
LbBiAddByDigit(N1, N2, sum);
LbBiClear(N1);
N1.dwUsed := sum.dwUsed;
N1.bSign := sum.bSign;
if (N1.IntBuf.dwLen < sum.IntBuf.dwLen) then
LbBiRealloc(N1, sum.IntBuf.dwLen);
LbBiCopy(N1 , sum, sum.dwUsed);
finally
LbBiFree(sum);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiSubByDigitInPlace(var N1 : LbInteger; N2 : byte);
var
diff : LbInteger;
begin
LbBiInit(diff, N1.dwUsed);
try
LbBiSubByDigit(N1, N2, diff);
LbBiClear(N1);
N1.dwUsed := diff.dwUsed;
N1.bSign := diff.bSign;
if (N1.IntBuf.dwLen < diff.IntBuf.dwLen) then
LbBiRealloc(N1, diff.IntBuf.dwLen);
LbBiCopy(N1 , diff, diff.dwUsed);
finally
LbBiFree(diff);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiReverseBytes(N1 : LbInteger; var N2 : LbInteger);
var
tmp_ptr : pByte;
cnt : integer; {!!03}
begin
tmp_ptr := N2.IntBuf.pBuf;
FillChar(N2, SizeOf(N2), $00);
N2.IntBuf.pBuf := tmp_ptr;
N2.bSign := N1.bSign;
N2.dwUsed := 0;
if (N2.IntBuf.dwLen < N1.IntBuf.dwLen) then
LbBiRealloc(N2, N1.IntBuf.dwLen);
for cnt := N1.dwUsed downto 1 do begin
LbBiAddByte(N2 , cAPPEND_ARRAY, LbBiGetByteValue(N1, cnt));
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiReverseBytesInPlace(var N1 : LbInteger);
var
rev : LbInteger;
begin
LbBiInit(rev, N1.IntBuf.dwLen);
try
LbBiReverseBytes (N1, rev);
LbBiClear(N1);
N1.dwUsed := rev.dwUsed;
N1.bSign := rev.bSign;
LbBiCopy(N1, rev, rev.dwUsed);
finally
LbBiFree(rev);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiReverseAllBits(N1 : LbInteger; var N2 : LbInteger);
var
i : integer; {!!03}
byt_ptr : pByte;
begin
LbBiReverseBytes(N1, N2);
byt_ptr := N2.IntBuf.pBuf;
for i := 1 to N2.dwUsed do begin
byt_ptr^ := LbBiReverseBits(byt_ptr^);
Inc(Longint(byt_ptr));
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiReverseBitsInPlace(var N1 : LbInteger);
var
rev : LbInteger;
begin
LbBiInit(rev, N1.IntBuf.dwLen);
try
LbBiReverseAllBits(N1, rev);
LbBiClear(N1);
N1.dwUsed := rev.dwUsed;
N1.bSign := rev.bSign;
LbBiCopy(N1, rev, rev.dwUsed);
finally
LbBiFree(rev);
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiAddBuf(var N1 : LbInteger; place : integer; buf : pByte; {!!03}
length : Integer);
var
totalLen : integer; {!!03}
ptr : pByte;
begin
if (place = cAPPEND_ARRAY) then begin
totalLen := succ(N1.dwUsed + integer(length)); {!!03}
if (totalLen > N1.IntBuf.dwLen) then
LbBiRealloc(N1, totalLen);
ptr := N1.IntBuf.pBuf;
inc(ptr, N1.dwUsed);
move(buf^, ptr^, length);
inc(N1.dwUsed, length);
end else begin
totalLen := pred(place) + integer(length); {!!03}
if (totalLen > N1.IntBuf.dwLen) then
LbBiRealloc(N1, totalLen);
ptr := N1.IntBuf.pBuf;
inc(ptr, pred(place));
move(buf^, ptr^, length);
if (N1.dwUsed < totalLen) then
N1.dwUsed := totalLen;
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiAddWord(var N1 : LbInteger; place : integer; N2 : word); {!!03}
begin
LbBiAddBuf(N1, place, @N2, SizeOf(word));
end;
{ ------------------------------------------------------------------- }
procedure LbBiAddDWord(var N1 : LbInteger; place : integer; N2 : integer);{!!03}
begin
LbBiAddBuf(N1, place, @N2, SizeOf(integer)); {!!03}
end;
{ ------------------------------------------------------------------- }
procedure LbBiCopyBigInt2Buf(N1 : LbInteger; place : integer; buf : pByte;{!!03}
length : Integer);
var
ptr : pByte;
begin
ptr := N1.IntBuf.pBuf;
inc(ptr, pred(place));
move(ptr^, buf^, length);
end;
{ ------------------------------------------------------------------- }
function LbBiCheckSimplePrimes(N1 : LbInteger) : Boolean;
{ returns true if N1 is not divisible by simple prime }
var
cnt : Integer;
quotient : LbInteger;
N2 : LbInteger;
remBN : LbInteger;
begin
LbBiInit(quotient, N1.dwUsed);
LbBiInit(N2 , 2);
LbBiInit(remBN, N1.dwUsed);
try
for cnt := 0 to cTotalSimple2KPrimes do begin
LbBiClear(N2);
LbBiAddWord(N2, cPREPEND_ARRAY, SimplePrimes[ cnt ]);
if LbBiCompare( N1, N2 ) = cEQUAL_TO then
break;
LbBiDiv(N1, N2, quotient, remBN);
if (not LbBiIsZero(quotient)) and
(not LbBiIsOne(quotient)) and LbBiIsZero(remBN) then begin
Result := False;
exit;
end;
end;
Result := True;
finally
LbBiFree(quotient);
LbBiFree(N2);
LbBiFree(remBN);
end;
end;
{ ------------------------------------------------------------------- }
function LbBiIsCompositFast(N1 : LbInteger; n : Integer) : Boolean;
var
w : LbInteger;
wMinus1 : LbInteger;
m : LbInteger;
b : LbInteger;
z : LbInteger;
a : Integer;
j : Integer;
i : Integer;
one : LbInteger;
random : TLbRandomGenerator;
Buf : pByte;
len : Integer;
begin
len := (N1.dwUsed div 2) + 1;
random := TLbRandomGenerator.create;
Buf := pByte(AllocMem(len));
LbBiInit(w, N1.dwUsed);
LbBiInit(wMinus1, N1.dwUsed);
LbBiInit(m, N1.dwUsed);
LbBiInit(b, len);
LbBiInit(z, N1.dwUsed);
LbBiInit(one, 2);
Result := True;
try
i := 1;
{ find w = 1 + (2^a) * m }
{ where m is odd and 2^a is the largest power of 2 dividing w - 1 }
LbBiCopy(w, N1, N1.dwUsed);
LbBiSubByDigit(w, $01, wMinus1);
if LbBiIsZero(wMinus1) then exit;
LbBiCopy(m, wMinus1, wMinus1.dwUsed);
a := 0;
while(not LbBiGetBit(wMinus1, a))do begin
LbBiShr(m, 1);
if LbBiIsZero(m) then exit;
inc(a);
end;
while True do begin
{ generate random number b: 1 < b < w }
LbBiAddByte(one, cPREPEND_ARRAY, $01);
while True do begin
random.RandomBytes(Buf^, len);
LbBiAddBuf(b, cPREPEND_ARRAY, Buf, len);
if (LbBiCompare(one, b) <> cLESS_THAN)or
(LbBiCompare(b, w) <> cLESS_THAN) then
continue;
break;
end;
j := 0;
{ z = b^m mod w }
LbBiPowerAndMod(b, m, w, z);
while True do begin
{ if j = 0 and z = 1 or z = w - 1 }
if ((j = 0) and LbBiIsOne(z))or
(LbBiCompare(z, wMinus1) = cEQUAL_TO) then begin
if i < n then begin { inc i and start over }
inc(i);
break;
end else begin { probably prime }
Result := False;
exit;
end;
end else begin
if (j > 0) and (LbBiIsOne(z)) then { not prime }
exit
else begin
inc(j);
if (j < a) then begin
LbBiMultInPlace(z, z);
LbBiModInPlace(z, w);
end else begin { not prime }
exit;
end;
end;
end;
end;
end;
finally
FreeMem(Buf, len);
LbBiFree(one);
LbBiFree(b);
LbBiFree(m);
LbBiFree(w);
LbBiFree(z);
LbBiFree(wMinus1);
random.Free;
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiRandomPrime(var N1 : LbInteger; Iterations : Byte);
var
tmp_byt : byte;
Buf : pByte;
len : Integer;
passed : Boolean;
random : TLbRandomGenerator;
begin
random := TLbRandomGenerator.create;
passed := False;
len := N1.IntBuf.dwLen;
Buf := pByte(AllocMem(len));
try
while(not passed)do begin
fillchar(Buf^, len, $00);
random.RandomBytes(Buf^, len);
LbBiAddBuf(N1, cPREPEND_ARRAY, Buf, len);
{ make it odd }
tmp_byt := LbBiGetByteValue(N1, 1);
tmp_byt := tmp_byt or $01;
LbBiAddByte(N1, 1, tmp_byt);
{ make sure it is a big number }
tmp_byt := LbBiGetByteValue(N1, N1.dwUsed);
tmp_byt := tmp_byt or $80;
LbBiAddByte(N1, N1.dwUsed, tmp_byt);
repeat
if LbBiCheckSimplePrimes(N1) then
if (not LbBiIsCompositFast(N1, Iterations)) then begin
passed := True;
break;
end;
LbBiAddByDigitInPlace(N1, 2);
until N1.dwUsed > integer(len); {!!03}
end;
finally
FreeMem(Buf, len);
random.Free;
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiRandomSimplePrime(var N1 : LbInteger);
var
x : Word;
RG : TLbRandomGenerator;
begin
RG := TLbRandomGenerator.create;
try
repeat
RG.RandomBytes(x, SizeOf(x));
x := x and $0FFF;
until(x > 3) and (x <= High(SimplePrimes));
LbBiAddWord(N1, cPREPEND_ARRAY, SimplePrimes[x]);
finally
RG.Free;
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiRandomBytes(var N1 : LbInteger; Count : Cardinal);
var
RG : TLbRandomGenerator;
begin
LbBiClear(N1);
LbBiReAlloc(N1, Count);
RG := TLbRandomGenerator.create;
try
RG.RandomBytes(N1.IntBuf.pBuf^, Count);
N1.dwUsed := Count;
finally
RG.Free;
end;
end;
{ ------------------------------------------------------------------- }
procedure LbBiExtendedEuclid(var u : LbInteger; var v : LbInteger;
var u1 : LbInteger; var u2 : LbInteger;
var GCD : LbInteger);
var
t1 : LbInteger;
t2 : LbInteger;
t3 : LbInteger;
zero : LbInteger;
k : Integer;
tmp : LbInteger;
begin
LbBiVerify(u);
LbBiVerify(v);
LbBiPrepare(u, v, u1);
LbBiPrepare(u, v, u2);
LbBiPrepare(u, v, GCD);
LbBiClear(u1);
LbBiClear(u2);
LbBiClear(GCD);
LbBiInit(tmp, cDEFAULT_PRECISION);
LbBiInit(t1, cDEFAULT_PRECISION);
LbBiInit(t2, cDEFAULT_PRECISION);
LbBiInit(t3, cDEFAULT_PRECISION);
LbBiInit(zero, 1);
try
LbBiAddByte(zero, cPREPEND_ARRAY, $00);
k := 0;
while((LbBiIsEven(u)) and (LbBiIsEven(v)))do begin
LbBiShr(u, 1);
LbBiShr(v, 1);
k := 1;
end;
if (LbBiCompare(u, v) = cLESS_THAN) then begin
LbBiSwap(u, v);
end;
{ u1 = 1 }
LbBiAddByte(u1, cPREPEND_ARRAY, $01);
{ u2 = 0 }
LbBiAddByte(u2, cPREPEND_ARRAY, $00);
{ GCD = u }
LbBiCopy(GCD, u, u.dwUsed);
{ t1 = v }
LbBiCopy(t1, v, v.dwUsed);
{ t2 = u-1 }
LbBiClear(tmp);
LbBiSubByDigit(u, $01, tmp);
LbBiCopy(t2, tmp, tmp.dwUsed);
{ t3 = v }
LbBiCopy(t3, v, v.dwUsed);
repeat { while t3 > 0 }
repeat { while LbBiIsEven(GCD) }
if (LbBiIsEven(GCD)) then begin
if (LbBiIsOdd(u1) or LbBiIsOdd(u2)) then begin
LbBiAddInPlace(u1, v);
LbBiAddInPlace(u2, u);
end;
LbBiShr(u1, 1);
LbBiShr(u2, 1);
LbBiShr(GCD, 1);
end;
if (LbBiIsEven(t3) or
(LbBiCompare(GCD, t3) = cLESS_THAN)) then begin
LbBiSwap(u1, t1);
LbBiSwap(u2, t2);
LbBiSwap(GCD, t3);
end;
until(LbBiIsOdd(GCD));
{ while(u1 < t1)or(u2 < t2) }
while((LbBiCompare(u1, t1) = cLESS_THAN) or
(LbBiCompare(u2, t2) = cLESS_THAN))do begin
LbBiAddInPlace(u1, v);
LbBiAddInPlace(u2, u);
end;
LbBiSubInPlace(u1, t1);
LbBiSubInPlace(u2, t2);
LbBiSubInPlace(GCD, t3);
until (LbBiCompare(t3, zero) = cLESS_THAN) or
(LbBiCompare(t3, zero) = cEQUAL_TO );
{ while(u1 <= v) and (u2 <= u) }
while(((LbBiCompare(u1, v) = cGREATER_THAN) or
(LbBiCompare(u1, v) = cEQUAL_TO)) and
((LbBiCompare(u2, u) = cGREATER_THAN) or
(LbBiCompare(u2, u) = cEQUAL_TO)))do begin
LbBiSubInPlace(u1, v);
LbBiSubInPlace(u2, u);
end;
LbBiShl(u1, k);
LbBiShr(u2, k);
LbBiShr(GCD, k);
finally
LbBiFree(tmp);
LbBiFree(t1);
LbBiFree(t2);
LbBiFree(t3);
LbBiFree(zero);
end;
end;
{ ------------------------------------------------------------------- }
function LbBiModInv(e : LbInteger; _mod : LbInteger; var d : LbInteger) : Boolean;
var
v : LbInteger;
u : LbInteger;
a : LbInteger;
b : LbInteger;
gcd : LbInteger;
begin
LbBiVerify(e);
LbBiVerify(_mod);
LbBiPrepare(e, _mod, d);
LbBiInit(u, cUSE_DEFAULT_PRECISION);
LbBiInit(v, cUSE_DEFAULT_PRECISION);
LbBiInit(a, cUSE_DEFAULT_PRECISION);
LbBiInit(b, cUSE_DEFAULT_PRECISION);
LbBiInit(gcd, cUSE_DEFAULT_PRECISION);
Result := False;
try
{ LbBiExtendedEuclid may switch the first two so send a local copy }
LbBiCopy(u, e, e.dwUsed);
LbBiCopy(v, _mod, _mod.dwUsed);
LbBiExtendedEuclid(u, v, a, b, gcd);
if (LbBiIsOne(gcd)) then begin
{ numbers valid }
LbBiSub(u, b, d);
Result := True;
end;
finally
LbBiFree(u);
LbBiFree(v);
LbBiFree(a);
LbBiFree(b);
LbBiFree(gcd);
end;
end;
{ == TLbLbInteger ========================================================= }
constructor TLbBigInt.Create(ALen : Integer);
var
prec : Integer;
begin
if (Alen < 1) then
prec := cUSE_DEFAULT_PRECISION
else
prec := ALen;
LbBiInit(FI, prec);
inherited Create;
end;
{ ------------------------------------------------------------------- }
destructor TLbBigInt.Destroy;
begin
LbBiFree(FI);
inherited Destroy;
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.SetSign(value : Boolean);
begin
LbBiVerify(FI);
if (value <> FI.bSign) then begin
FI.bSign := value;
end;
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.getSign : Boolean;
begin
LbBiVerify(FI);
Result := FI.bSign;
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.Add(I2 : TLbBigInt);
var
tmp : LbInteger;
begin
LbBiInit(tmp, cUSE_DEFAULT_PRECISION);
try
LbBiCopy(tmp, I2.Int, I2.Int.dwUsed);
LbBiVerify(tmp);
LbBiAddInPlace(FI, tmp);
finally
LbBiFree(tmp);
end;
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.Subtract(I2 : TLbBigInt);
var
tmp : LbInteger;
begin
LbBiVerify(FI);
LbBiInit(tmp, cUSE_DEFAULT_PRECISION);
try
LbBiCopy(tmp, I2.Int, I2.Int.dwUsed);
LbBiVerify(tmp);
LbBiSubInPlace(FI, tmp);
finally
LbBiFree(tmp);
end;
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.Multiply(I2 : TLbBigInt);
var
tmp : LbInteger;
begin
LbBiVerify(FI);
LbBiInit(tmp, cUSE_DEFAULT_PRECISION);
try
LbBiCopy(tmp, I2.Int, I2.Int.dwUsed);
LbBiVerify(tmp);
LbBiMultInPlace(FI, tmp);
finally
LbBiFree(tmp);
end;
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.Divide(I2 : TLbBigInt);
var
tmp : LbInteger;
rem : LbInteger;
begin
LbBiVerify(FI);
LbBiInit(tmp, cUSE_DEFAULT_PRECISION);
LbBiInit(rem, cUSE_DEFAULT_PRECISION);
try
LbBiCopy(tmp, I2.Int, I2.Int.dwUsed);
LbBiVerify(tmp);
LbBiDivInPlace(FI, tmp, rem);
finally
LbBiFree(tmp);
LbBiFree(rem);
end;
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.Modulus(I2 : TLbBigInt);
var
tmp : LbInteger;
begin
LbBiVerify(FI);
LbBiInit(tmp, cUSE_DEFAULT_PRECISION);
try
LbBiCopy(tmp, I2.Int, I2.Int.dwUsed);
LbBiVerify(tmp);
LbBiModInPlace(FI, tmp);
finally
LbBiFree(tmp);
end;
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.SubtractByte(b : byte);
begin
LbBiVerify(FI);
LbBiSubByDigitInPlace(FI, b);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.MultiplyByte(b : byte);
begin
LbBiVerify(FI);
LbBiMulByDigitInPlace(FI, b);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.DivideByte(b : byte);
var
rem : byte;
begin
LbBiVerify(FI);
LbBiDivByDigitInPlace(FI, b, rem);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.ModByte(b : byte);
var
rem : byte;
begin
LbBiVerify(FI);
LbBiDivByDigitInPlace(FI, b, rem);
LbBiClear(FI);
LbBiAddByte(FI, cPREPEND_ARRAY, rem);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.AddByte(b : byte);
begin
LbBiVerify(FI);
LbBiAddByDigitInPlace(FI, b);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.Clear;
begin
LbBiClear(FI);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.Trim;
begin
LbBiVerify(FI);
LbBiTrimSigZeros(FI);
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.Compare(I2 : TLbBigInt) : ShortInt;
var
tmp : LbInteger;
begin
LbBiVerify(FI);
LbBiInit(tmp, I2.Int.dwUsed);
try
LbBiCopy(tmp, I2.Int, I2.Int.dwUsed);
LbBiVerify(tmp);
Result := LbBiCompare(FI, tmp);
finally
LbBiFree(tmp);
end;
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.Abs(I2 : TLbBigInt): ShortInt;
var
tmp : LbInteger;
begin
LbBiVerify(FI);
LbBiInit(tmp, cUSE_DEFAULT_PRECISION);
try
LbBiCopy(tmp, I2.Int, I2.Int.dwUsed);
LbBiVerify(tmp);
Result := LbBiAbs(FI, tmp);
finally
LbBiFree(tmp);
end;
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.IsZero : Boolean;
begin
LbBiVerify(FI);
Result := LbBiIsZero(FI);
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.IsOne : Boolean;
begin
LbBiVerify(FI);
Result := LbBiIsOne(FI);
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.IsComposite(Iterations : Cardinal) : Boolean;
begin
LbBiVerify(FI);
Result := true;
if LbBiCheckSimplePrimes(FI) then
if (not LbBiIsCompositFast(FI, Iterations)) then
Result := false;
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.Copy(I2 : TLbBigInt);
begin
Clear;
LbBIMove(FI, I2.Int, cAPPEND_ARRAY, I2.Size);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.CopyLen(I2 : TLbBigInt; Len : Integer);
begin
Clear;
LbBIMove(FI, I2.Int, cAPPEND_ARRAY, Len);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.CopyByte(b : byte);
begin
Clear;
LbBiAddByte(FI, cPREPEND_ARRAY, b);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.CopyWord(w : word);
begin
Clear;
LbBiAddWord(FI, cPREPEND_ARRAY, w);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.CopyDWord(d : dword);
begin
Clear;
LbBiAddDWord(FI, cPREPEND_ARRAY, d);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.CopyBuffer(const Buf; BufLen : Integer);
begin
Clear;
LbBiAddBuf(FI, cPREPEND_ARRAY, @Buf, BufLen);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.Append(I : TLbBigInt);
begin
LbBIMove(FI, I.Int, cAPPEND_ARRAY, I.Size);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.AppendByte(b : byte);
begin
LbBiAddByte(FI, cAPPEND_ARRAY, b);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.AppendWord(w : word);
begin
LbBiAddWord(FI, cAPPEND_ARRAY, w);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.AppendDWord(d : dword);
begin
LbBiAddDWord(FI, cAPPEND_ARRAY, d);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.AppendBuffer(const Buf; BufLen : Integer);
begin
LbBiAddBuf(FI, cAPPEND_ARRAY, @Buf, BufLen);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.Prepend(I : TLbBigInt);
begin
LbBIMove(FI, I.Int, cPREPEND_ARRAY, I.Size);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.PrependByte(b : byte);
begin
LbBiAddByte(FI, cPREPEND_ARRAY, b);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.PrependWord(w : word);
begin
LbBiAddWord(FI, cPREPEND_ARRAY, w);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.PrependDWord(d : dword);
begin
LbBiAddDWord(FI, cPREPEND_ARRAY, d);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.PrependBuffer(const Buf; BufLen : Integer);
begin
LbBiAddBuf(FI, cPREPEND_ARRAY, @Buf, BufLen);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.RandomPrime(Iterations : Byte);
begin
LbBiRandomPrime(FI, Iterations);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.RandomSimplePrime;
begin
LbBiRandomSimplePrime(FI);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.RandomBytes(Count : Cardinal);
begin
LbBiRandomBytes(FI, Count);
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.ToBuffer(var Buf; BufLen : Integer ) : integer;
var
len : Integer;
begin
// LbBiVerify(FI);
len := Min(FI.dwUsed, BufLen);
result := len;
LbBiCopyBigInt2Buf(FI, cPREPEND_ARRAY, @Buf, len);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.ReverseBits;
begin
LbBiVerify(FI);
LbBiReverseBitsInPlace(FI);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.ReverseBytes;
begin
LbBiVerify(FI);
LbBiReverseBytesInPlace(FI);
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.IsOdd : Boolean;
begin
LbBiVerify(FI);
Result := LbBiIsOdd(FI);
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.IsEven : Boolean;
begin
LbBiVerify(FI);
Result := LbBiIsEven(FI);
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.GetBit(bit : Integer) : Boolean;
begin
LbBiVerify(FI);
Result := LbBiGetBit(FI, bit);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.Shr_(_shr : Integer);
begin
LbBiVerify(FI);
LbBiShr(FI, _shr);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.Shl_(_shl : Integer);
begin
LbBiVerify(FI);
LbBiShl(FI, _shl);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.XOR_(I2 : TLbBigInt);
begin
LbBiVerify(FI);
LbBiXORInPlace(FI, I2.Int);
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.OR_(I2 : TLbBigInt);
begin
LbBiVerify(FI);
LbBiORInPlace(FI, I2.Int);
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.ModInv(Modulus : TLbBigInt) : Boolean;
var
tmp : LbInteger;
x : LbInteger;
begin
LbBiInit(tmp, cUSE_DEFAULT_PRECISION);
LbBiInit(x, cUSE_DEFAULT_PRECISION);
try
LbBiCopy(tmp, Modulus.Int, Modulus.Int.dwUsed);
LbBiVerify(tmp);
Result := LbBiModInv(FI, tmp, x);
LbBiClear(FI);
LbBiCopy(FI, x, x.dwUsed);
finally
LbBiFree(tmp);
LbBiFree(x);
end;
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.GetSize : integer; {!!03}
begin
Result := FI.dwUsed;
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.GetIntStr : string;
begin
Result := BufferToHex(IntBuf^, FI.dwUsed);
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.GetIntBuf : pByte;
begin
Result := FI.IntBuf.pBuf;
end;
{ ------------------------------------------------------------------- }
procedure TLbBigInt.PowerAndMod(Exponent : TLbBigInt; Modulus : TLbBigInt);
begin
LbBiPowerAndModInPLace(FI, Exponent.Int, Modulus.Int);
end;
{ ------------------------------------------------------------------- }
function TLbBigInt.GetByteValue( place : integer ) : Byte;
begin
LbBiVerify(FI);
result := LbBiGetByteValue( FI, place );
end;
end.
Delphi
1
https://gitee.com/wilmerxu/nginx-tool.git
git@gitee.com:wilmerxu/nginx-tool.git
wilmerxu
nginx-tool
nginx-tool
master

搜索帮助