Women, you can't live with 'em..... and you can't live with 'em!
Als je hoort hoe het klokje thuis tikt, zit je niet in het café.
1
2
3
4
5
6
7
8
| Type persoon naam as String adres as String leeftijd as integer End Type Dim p as Persoon p.Naam="bladiebla" |
Voor grote getallen kun je beter een array of string gebruiken, een linked list is ook nog wel te doen, maar ik weet niet in hoeverre dat mogelijk is in VB.
- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!
ik had een getal van ongeveer 1E317 ofzo...Op woensdag 14 november 2001 18:08 schreef r-e-m het volgende:
Een Double gaat tot 1.79769313486232E308
Is niet groot genoeg??
misschien zit er ook wel een fout in de code, ik zal de code er vanavond wel even op zetten, dan kan die gecontroleerd worden, ik moet nu weg..
Women, you can't live with 'em..... and you can't live with 'em!
Als je hoort hoe het klokje thuis tikt, zit je niet in het café.
het is zoals je waarschijnlijk ziet een deel van het RSA algoritme
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| Private Sub Command3_Click() Dim p As Double, q As Double, n As Double, a As Double, e As Double, d As Double, c As Double, m As Double p = 13 q = 17 n = p * q a = (p - 1) * (q - 1) e = 5 d = 77 m = arrGait(1) c = m ^ e Mod 221 Text2.Text = c End Sub |
arrGait is de array waar de desbetreffende ascii code uitgehaald moet worden om omgezet te worden in ciphertext, ik heb plaats 1 als voorbeeld genomen en dat is 84 in mijn geval
de fout wordt steeds gegeven wanneer de berekening c = m^e mod 221 wordt uitgevoerd
iemand misschien een idee waar ik fout zit of die misschien een betere methode weet om dit uit te rekenen?
[edit]
nu ik trouwens even helder nadenk
ik heb in dit voorbeeld e = 5 gekozen waardoor de waarde van m^e veel kleiner wordt en nooit een overflow kan geven...
er zit dus gewoon een fout in de code, iemand een idee??
Women, you can't live with 'em..... and you can't live with 'em!
Als je hoort hoe het klokje thuis tikt, zit je niet in het café.
84^5 = 4182119424, past dus niet in een integer...
Je moet minimaal een cardinal zien te krijgen (kijk ff in de vb help, misschien dat dat ook een dword kan heten), want dat zijn untyped integers en kunnen dus tot 4294967295.
Maar daarmee los je het probleem niet op, want veel groter dan 84^5 kun je met integer types niet gaan. Tijd om de type declaratie van c aan te passen in bv een double, die heeft (uit de Delphi help, heb hier geen VB) een range van 5.0 x 10^324 .. 1.7 x 10^308en dat moet voorlopig toch genoeg zijn lijkt me. Kortom: zoek in de help naar datatype met de grootste range.
(edit) hmmm ik had de boel niet helemaal goed gelezen, ook een double gaat je niet genoeg ruimte opleveren.
Declareer in ieder geval die c keihard als double, dan ben je hier van de overflow bij 84^5 af, want dat komt volgens mij omdat VB er intern een integer van maakt.
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
En waarom niet? Als je de rest van de deling van 36.729429374 door 6 wilt weten, met cijfers achter de komma, kun je erg moeilijk een Integer gebruiken. Enige punt is, en dat hoef je niet zo moeilijk uit te leggen met hoe een Double wordt opgeslagen, is dat Mod wel een Integer teruggeeft, en die dus afrondt. Daarom kun je geen Mod met een Double gebruiken.Op donderdag 15 november 2001 08:09 schreef Janoz het volgende:
hmm .. Hoe zou je op een double een mod uit willen voeren? Een double heeft een floating point. Dat wil zeggen dat ze een double in 2 getallen opslaan. Het eerste getal is een getal in de range [0,1). Het tweede getal geeft de positie van de komma aan. Bij hele grote getallen weet de computer niet meer wat het eerste getal na de komma! Er kan dus nooit een rest berekend worden van een deling.
Anyways... Ik denk dat het iig wel ligt aan die Mod. Als ik 84 ^ 5 in een Double pleur, werkt het wel. Ik denk dat het resultaat van die Mod 221 groter is dan 32767, het maximum voor een Integer. Ik denk dat of je berekening niet klopt (je moet misschien wel geen Mod gebruiken) of je moet zelf een Mod-functie schrijven...
1
2
3
4
5
6
7
8
9
| Function DoubleMod(ByVal A As Double, B As Integer) As Double
Do While A > B
If A > (100 * B) Then A = A - (100 * B)
If A > (10 * B) Then A = A - (10 * B)
If A > B Then A = A - B
Loop
DoubleMod = A
End Function |
Is een beetje sneller dan normaal:
1
2
3
| Do While A > B
A = A - B
Loop |
Maar goed ik heb je iig een b-tje op weg geholpen...
.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?
c = CDbl(CLng(m^e) Mod 221)
Eigenlijk moet je een TRUNCATE doen. Ik heb VB op dit moment niet openstaan, dus kan ik het hier niet testen. Ik zou zeggen: doe een SEARCH in de help-file van VB op "truncate" en je zult wel iets vinden.
Om een modulo te berekenen kan je op het volgende letten als je de performance wat vooruit wil helpen: de modulo van X / Y is maximaal zo groot als het kleinste van de 2 getallen. Dus als X>Y, dan is Y je maximum modulo. Het wordt nog mooier als Y>X, want dan is je modulo gewoon gelijk aan X. Als X=Y, dan is je modulo natuurlijk gelijk aan 0.
PC: R5-2600X | X370-Pro | 2x8GB | 960Pro 512GB | WD 4TB | GTX 660 | Eizo CX240 | Steinberg UR22MkII | JBL LSR305
Dat stukje code is wel leuk enzo ;P maar het werkt niet beter dan zonder CDbl en CLng. Zoals ik al zei, het resultaat van de Mod is waarschijnlijk te groot om in een Integer te passen. Alhoewel me dat niet echt logisch lijkt, omdat de modulo van x / y altijd kleiner moet zijn dan y. Toch?Op donderdag 15 november 2001 08:40 schreef apa het volgende:
Als je de modulo wil berekenen, dan moet je erop letten dat je dat enkel doet van een INTEGER waarde! Jij berekent de modulo van m^e. Zowel 'm' als 'e' zijn gedefinieerd als DOUBLE's. Het resultaat van m^e is dan ook een DOUBLE, en daarmee kan je geen modulo berekenen. Je zou het als volgt moeten doen:
c = CDbl(CLng(m^e) Mod 221)
[..]
Om een modulo te berekenen kan je op het volgende letten als je de performance wat vooruit wil helpen: de modulo van X / Y is maximaal zo groot als het kleinste van de 2 getallen. Dus als X>Y, dan is Y je maximum modulo. Het wordt nog mooier als Y>X, want dan is je modulo gewoon gelijk aan X. Als X=Y, dan is je modulo natuurlijk gelijk aan 0.
Hmmz... nu ik een beetje zit te prutsen lijkt het me dat het probleem zit in het feit dat 84 ^ 5 (4182119424) too f*cking large is om in een Long te gieten, omdat de limiet daar 2147483647. Daar zit dus de fout, wat Delphi32 ook al zei.
.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?
Dus jij wilt beweren dat een double met een waarde van 1.79769313486232E308 nog precies ALLE 308 cijfers weet die voor de komma komen?Op donderdag 15 november 2001 08:29 schreef Xenophage het volgende:
[..]
En waarom niet? Als je de rest van de deling van 36.729429374 door 6 wilt weten, met cijfers achter de komma, kun je erg moeilijk een Integer gebruiken. Enige punt is, en dat hoef je niet zo moeilijk uit te leggen met hoe een Double wordt opgeslagen, is dat Mod wel een Integer teruggeeft, en die dus afrondt. Daarom kun je geen Mod met een Double gebruiken.
Als je het nog niet begrijpt, dan wil ik het nog wel een keertje voor je uitleggen hoor....
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Nee, dat zeg ik niet. Ik zeg alleen dat het misschien wel handig is als je bij een modulo cijfers achter komma krijgt. Ik weet heus wel dat je bij een Double of een Single maar een bepaald aantal cijfers achter de komma krijgt.Op donderdag 15 november 2001 09:01 schreef Janoz het volgende:
[..]
Dus jij wilt beweren dat een double met een waarde van 1.79769313486232E308 nog precies ALLE 308 cijfers weet die voor de komma komen?
Als je het nog niet begrijpt, dan wil ik het nog wel een keertje voor je uitleggen hoor....
Do not underestimate me...
.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?
Zelfs maar een bepaald aantal cijfers voor de comma!Op donderdag 15 november 2001 09:12 schreef Xenophage het volgende:
[..]
Nee, dat zeg ik niet. Ik zeg alleen dat het misschien wel handig is als je bij een modulo cijfers achter komma krijgt. Ik weet heus wel dat je bij een Double of een Single maar een bepaald aantal cijfers achter de komma krijgt.
Do not underestimate me...
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
Mwoh ach, als je vijftien cijfers voor de komma (wat trouwens met een k is) weinig noemt... Ik denk dat het voldoende is voor bijna alle berekeningen. En als je me niet gelooft...Op donderdag 15 november 2001 09:32 schreef Janoz het volgende:
[..]
Zelfs maar een bepaald aantal cijfers voor de comma!
1
2
3
4
5
| Dim I As Double I = 2 ^ 40 MsgBox I |
Uitkomst: 562949953421312
.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?
Bij een floating point getal kun je niet garanderen dat het eerste getal voor de komma uberhaupt bekend is. ALs er al een getal staat, kun je nog niet eens garanderen of dit getal wel het juiste getal is. Zodra de mantis hoger is dan het aantal bits waarin de fraction wordt opgeslagen is de preciese waarde van het gehele getal niet meer bekend.Op donderdag 15 november 2001 09:38 schreef Xenophage het volgende:
Mwoh ach, als je vijftien cijfers voor de komma (wat trouwens met een k is) weinig noemt... Ik denk dat het voldoende is voor bijna alle berekeningen. En als je me niet gelooft...
Ik vertrouw de berekeningen van VB trouwens nu al helemaal niet meer:
240=210 * 210 * 210 * 210
=1024 * 1024 * 1024 * 1024
=1048576 * 1048576
1
2
3
4
5
6
7
8
9
10
11
| 1048576
1048576 *
---------
6291456
73400320
524288000
8388608000
41943040000
1048576000000 +
-------------
1099511627776 |
En dat is toch iets anders dan jij daar hebt staan...
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
deze doet het dus en werkt ook redelijk snel..Op donderdag 15 november 2001 08:29 schreef Xenophage het volgende:
[..]
En waarom niet? Als je de rest van de deling van 36.729429374 door 6 wilt weten, met cijfers achter de komma, kun je erg moeilijk een Integer gebruiken. Enige punt is, en dat hoef je niet zo moeilijk uit te leggen met hoe een Double wordt opgeslagen, is dat Mod wel een Integer teruggeeft, en die dus afrondt. Daarom kun je geen Mod met een Double gebruiken.
Anyways... Ik denk dat het iig wel ligt aan die Mod. Als ik 84 ^ 5 in een Double pleur, werkt het wel. Ik denk dat het resultaat van die Mod 221 groter is dan 32767, het maximum voor een Integer. Ik denk dat of je berekening niet klopt (je moet misschien wel geen Mod gebruiken) of je moet zelf een Mod-functie schrijven...
code:
1 2 3 4 5 6 7 8 9Function DoubleMod(ByVal A As Double, B As Integer) As Double Do While A > B If A > (100 * B) Then A = A - (100 * B) If A > (10 * B) Then A = A - (10 * B) If A > B Then A = A - B Loop DoubleMod = A End Function
maar het hele programma draait niet snel genoeg naar mijn mening.
dit is de volledige code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| Private Function ToAscii(strInput As String) As Integer()
FUNCTIE OM DE LETTERS OM TE ZETTEN IN ASCII EN IN EEN ARRAY TE ZETTEN
End Function
Function DoubleMod(ByVal c As Double, n As Integer) As Double
Do While c > n
If c > (100 * n) Then c = c - (100 * n)
If c > (10 * n) Then c = c - (10 * n)
If c > n Then c = c - n
Loop
DoubleMod = c
End Function
Private Sub Command1_Click()
Dim p As Integer, q As Integer, n As Integer, a As Integer
Dim e As Integer, d As Integer, c As Double, m As Integer
Dim c1 As Integer, strOutput As String, arrGait() As Integer
Dim arrGait2() As Integer
'alle waardes voor het RSA algoritme worden vastgelegd
p = 13
q = 17
n = p * q
a = (p - 1) * (q - 1)
e = 5
d = 77
'de benodigde velden worden geleegd
List1.Clear
Text2.Text = ""
'arrGait wordt gevuld met ascii codes van de letters van tekstvak 1
arrGait = ToAscii(Text1.Text)
ReDim arrGait2(Len(Text1.Text))
'tekst 1 wordt gecodeerd
For i = 0 To Len(Text1.Text) - 1
m = arrGait(i)
c = m ^ e
c1 = DoubleMod(c, n) 'de ciphertext wordt berekend
List1.AddItem (c1)
Text2.Text = Text2.Text & Chr$(List1.List(i)) 'de gecodeerde ascii codes worden omgezet en in het tekstvak gezet
Next i
End Sub |
iemand een idee hoe ik dit sneller/compacter kan maken?
[edit]
gecompileerd draait ie toch wel redelijk:
een tekst van ongeveer 80 tekens duurde 28 seconden
misschien is het een idee om waardes voor bepaalde letters op te slaan zodat die niet elke keer opnieuw berekend hoeven te worden..
Women, you can't live with 'em..... and you can't live with 'em!
Als je hoort hoe het klokje thuis tikt, zit je niet in het café.