Toon posts:

[ALG] Decimaal naar Hexadecimaal

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik wil een groot getal van decimaal naar hexadecimaal converteren in VBScript (/ASP). Hiervoor is de standaard hex functie niet toereikend (overflow). Ik ben dus op zoek naar een stukje maatwerk dec2hex.

Ik heb zelf dit scriptje gevonden:
JavaScript:
1
2
3
4
5
6
7
8
9
10
function dec2hex(i)
{
  var sHex = "0123456789ABCDEF";
  var h = "";
  for(j = 0; j <= 3; j++)
  {
    h += sHex.charAt((i >> (j * 8 + 4)) & 0x0F) + sHex.charAt((i >> (j * 8)) & 0x0F);
  }
  return h;
}

Deze functie wil ik nu in VBScript (/ASP) hebben. Dit is mijn conversie:

Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
function dec2hex(i)
{
  dim sHex : sHex = "0123456789ABCDEF"
  dim h,j
  for j=0 to 3
    l = mid(sHex,(i / 2^(j * 8 + 4)) & 0x0F,1)
    r = mid(sHex,(i / 2^(j * 8)) & 0x0F,1)
    h = h & l & r
  next 'i
  dec2hex = h
}

Dit gaat best vaak goed, maar ik krijg bij 'r' een overflow wanneer ik voor het getal i 2154132085 invul. Dit blijkt te liggen aan de 'AND'-operatie met 0x0F. Ja, tis een joekel van een getal, maar die heb ik nodig bij m'n MD5 berekening... Wie weet 't beter....?

[ Voor 0% gewijzigd door Verwijderd op 16-09-2002 14:43 . Reden: Verheldering ]


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

Tuurlijk krijg je een overflow. Een overflow krijg je omdat het getal te groot wordt. Of je nu met een string begint of niet. Je antwoord wordt gewoon te groot. De enige oplossign is om
1 Het in een double op te slaan, maar dan wordt het getal afgerond waardoor je gegevens gaat missen
2 Ook de boel in een string uitvoeren, maar dan zul je behoorlijk wat meer moeten implementeren (hoe zou je anders een string door 16 moeten delen?)

Is er in VB niet een component waarmee je met grote getallen kunt werken?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Pooh
  • Registratie: April 2001
  • Niet online

Pooh

Lees eens een boek

Verwijderd schreef op 16 september 2002 @ 14:38:
Ik wil een groot getal van decimaal naar hexadecimaal converteren in VBScript (/ASP). Hiervoor is de standaard hex functie niet toereikend (overflow). Ik ben dus op zoek naar een stukje maatwerk dec2hex.

Ik heb zelf dit scriptje gevonden:
<----------8X----------->

Dit gaat best vaak goed, maar ik krijg bij 'r' een overflow wanneer ik voor het getal i 2154132085 invul. Dit blijkt te liggen aan de 'AND'-operatie met 0x0F. Ja, tis een joekel van een getal, maar die heb ik nodig bij m'n MD5 berekening... Wie weet 't beter....?
Tsja. Andere programmeertaal kiezen? Een library voor extreme getallen gebruiken? Een string-conversie-algoritme schrijven? Mogelijkheden genoeg. Overigens snap ik even niet wat er mis is met de bestaande md5-algortimes. :?

Verwijderd

Topicstarter
Ik heb de instructies even uitgesplitst:

Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
function dec2hex(i)
  dim j,h,x1,x2 : h=""
  for j=0 to 3
    x1 = i / 2^(j * 8 + 4)
    x1 = x1 and &H0F
    x2 = i / 2^(j * 8)
    x2 = x2 AND &H0F
    h = h & mid(sHex,x1+1,1)&mid(sHex,x2+1,1)
  next 'j
  dec2hex = "&H"&h
end function

De fout komt hier in 7. Het komt er dus op neer dat {2154132085 AND &H0F} een overflow geeft. Het getal 2154132085 is dus blijkbaar nog geen overflow (anders had de fout al in regel 6 moeten ontstaan).
De uitkomst van de berekening (AND &H0F) ligt tussen de 0 en de 15, dus deze kan ook geen overflow veroorzaken (zou ik zeggen).

Het zit 'm dus blijkbaar enkel in de AND-operatie...blijft de vraag over: hoe maak ik het getal x2 kleiner, zonder dat de uitkomst van de AND verandert...

Verwijderd

Topicstarter
Ugh, dom! Gewoon: if x2>100000000 then x2 = x2-100000000 oid :)

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

*zucht*

2154132085 is hexadecimaal 80657275. Dit is alleen op te slaan in een UNSIGNED long. De max waarde voor signed longs is 7FFFFFFF. Waarschijnlijk gaat VB er automatisch een double van maken aangezien het getal voorbij het bereik komt. Voor de and operatie moet ie het echter weer terug zetten naar een long (een AND operatie werkt niet op een double) en dan krijg je je overflow.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • Pooh
  • Registratie: April 2001
  • Niet online

Pooh

Lees eens een boek

Janoz schreef op 16 september 2002 @ 15:25:
*zucht*

2154132085 is hexadecimaal 80657275. Dit is alleen op te slaan in een UNSIGNED long. De max waarde voor signed longs is 7FFFFFFF. Waarschijnlijk gaat VB er automatisch een double van maken aangezien het getal voorbij het bereik komt. Voor de and operatie moet ie het echter weer terug zetten naar een long (een AND operatie werkt niet op een double) en dan krijg je je overflow.
Aaargh... :X
Topicstarter: Probeer alsjeblieft al je variabelen even "strak" te definieren. (Dus alle variants enzo eruit, en "option explicit" bovenin je file).

Verwijderd

Topicstarter
Maar het klopt toch dat ik in principe een hele hoop van dat getal af kan hakken omdat ie er als het ware een mask overheen legt met die AND operatie?

code:
1
2
3
4
1001010010101010 (bijvoorbeeld)
0000000000001111 AND
--------------------------
0000000000001010


De rest (100101001010xxxx) kan er dan toch zonder meer vanaf getrokken worden?

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

nogmaals:een AND operatie werkt niet op een double. Bij een double weet je helemaal niet wat nu die laatste paar bits zijn omdat ze bij zo'n groot getal buiten de significantie vallen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Topicstarter
Ugh.
Het blijkt dus dat de bovenstaande code in JS niet te converteren is naar VB?
Ik heb nu de JS-versie geïnclude. Deze werkt perfect.

Best triest dat de scripttaaltjes niet onderling uitwisselbaar zijn... ;(
Dan maar mixed-language... :r

(Note: dit is een onderdeel van een project dat al 2 jaar draait. Ik kan dus niet zomaar alles omgooien, helaas)

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 28-08 12:00

Janoz

Moderator Devschuur®

!litemod

Wie zegt dat er nu wel een juist antwoord uitkomt? Het kan natuurlijk ook zijn dat jscript wel een and op double's heeft gedefinieerd. Dit betekend alleen niet dat dit ook gaat werken zoals je verwacht!.. Let daar goed op.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Topicstarter
Die JS-versie heb ik niet zelf geschreven, dus die werkt :P

http://pajhome.org.uk/crypt/md5/index.html

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-08 23:12
In VB kun je ook een Variant geforceerd naar Decimal type gebruiken. Dat zag er ongeveer zo uit:

Visual Basic:
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
42
43
44
45
46
47
48
49
50
51
52
53
54
'**************************************************************************************
'*                                                                                    *
'*        Convert a long decimal number (string) to a hexadecimal number (string)     *
'*                                                                                    *
'**************************************************************************************
Public Function Dec2Hex(DecString As String, MaxDecPos As Integer, MaxHexPos As Integer) As String

  Const MAX_DEC_POS As Integer = 28
  
  Const ERR_STRING As String = "Error !"
    
  ' Do some checks. No longer than MAX_DEC_POS or MaxDecPos decimal positions and
  ' no greater than MAX_HEX_POS positions.
  ' ( Which should always succeed if the first check succeeds anyway. )
  If Len(DecString) > MAX_DEC_POS Or Len(DecString) > MaxDecPos Then
    Dec2Hex = ERR_STRING
    Exit Function
  End If
  
  Dim OrigNumber As Variant
  
  OrigNumber = CDec(DecString)
  
  If OrigNumber / (16 ^ (MaxHexPos - 1)) > &HF Then
    Dec2Hex = ERR_STRING
    Exit Function
  End If
  
  Dim HexPos As Integer: Dim HexPosVal As Integer
  Dim Remaining As Variant: Dim Hexstring As String
  
  ' Set remaining to original value
  Remaining = OrigNumber
  For HexPos = MaxHexPos - 1 To 0 Step -1
  
    ' Calculate the value for this hex position ( 16 ^ HexPos )
    HexPosVal = Int(Remaining / (16 ^ HexPos))
    
    ' Subtract it from the remaining value
    Remaining = Remaining - CDec(HexPosVal * 16 ^ HexPos)
    
    ' Paste it to the hex string returned, while converting to a hex number
    Hexstring = Hexstring & Hex$(HexPosVal)
    
  Next HexPos
  
  ' This should never happen ofcourse !
  If Remaining <> 0 Then
    Dec2Hex = ERR_STRING
  Else
    Dec2Hex = Hexstring
  End If

End Function



VBscript weet ik eigenlijk niet of zoiets kan ...

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1