nullschritt Posted August 21, 2012 Posted August 21, 2012 I am converting text into a custom base system, and when it's converted back I am using a custom _dec() function, the problem is, when I do _dec() I get the numbers, and I don;t know how to change them into text, I have tried chr, and chrw, with no luck, how do I turn dec back into regular text? this is the process text -> dec -> (custom base104) -> dec ??-> text
Danyfirex Posted August 21, 2012 Posted August 21, 2012 (edited) did you try with Hex? Edited August 21, 2012 by Danyfirex Danysys.com AutoIt... UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut
AZJIO Posted August 21, 2012 Posted August 21, 2012 Show your function _dec(), but I do not understand the question. My other projects or all
nullschritt Posted August 21, 2012 Author Posted August 21, 2012 (edited) expandcollapse popupFunc _Base($iDecNumber, $sChar) Local $aBase = StringSplit($sChar, ",") Local $iBase = $aBase[0] Local $iLen = Int(Log($iDecNumber) / Log($iBase)) + 1 Dim $iUnit[$iLen + 1] Local $iReturn Local $iTemp = $iDecNumber If $aBase[0] <> $iBase Then SetError(1) Return -1 EndIf If $iDecNumber = 0 Then Return $aBase[1] For $i = 1 To $iLen For $i2 = 1 To $i - 1 $iTemp = $iTemp / $iBase Next $iUnit[$i] = $aBase[Mod($iTemp, $iBase) + 1] $iTemp = $iDecNumber Next For $i = 1 To $iLen $iReturn = $iUnit[$i] & $iReturn Next Return $iReturn EndFunc ;==>_Base Func _Dec($iNumber, $sChar) Local $iReturn Local $aBase = StringSplit($sChar, ",") Local $iBase = $aBase[0] Local $aTemp = StringRegExp($iNumber, "[a-zA-Z0-9:+¦/]{" & StringLen($aBase[1]) & "}", 3) For $i = 0 To UBound($aTemp) - 1 $iReturn += ($iBase ^ $i) * (_ArraySearch($aBase, $aTemp[UBound($aTemp) - 1 - $i], 0, 0, 1) - 1) Next Return $iReturn EndFunc ;==>_Dec and you'll probably want to see this. Global $base104 = "H¦,He,Li,Be,B¦,C¦,N¦,O¦,F¦,Ne,Na,Mg,Al,Si,P¦,S¦,Cl,Ar,K¦,Ca,Sc,Ti,Cr,Mn,Fe,Co,Ni,Cu,Zn,Ga,Ge,As,Se,Br,Kr,Rb,Sr,Y¦,Zr,Nb,Mo,Tc,Ru,Rh,Pd,Ag,Cd,In,Sn,Sb,Te,I¦,Xe,Cs,Ba,La,Ce,Pr,Nd,Pm,Sm,Eu,Gd,Tb,Dy,Ho,Er,Tm,Yb,Lu,Hf,Ta,W¦,Re,Os,Ir,Pt,Au,Hg,Tl,Pb,Bi,Po,At,Rn,Fr,Ra,Ac,Th,Pa,U¦,Np,Pu,Am,Cm,Bk,Cf,Es,Fm,Md,No,Bh,Rg,Fl" Off the top of my head I don't see a way to interface your code and mine, but I also havn't slept much, so I will look at it again in a few hours, in the mean time, any help is appreciated. Edited August 21, 2012 by nullschritt
nullschritt Posted August 21, 2012 Author Posted August 21, 2012 did you try with Hex?Yes, it just returned even bigger numbers with zero-padding.
czardas Posted August 21, 2012 Posted August 21, 2012 (edited) Basically what you have here is code to convert from decimal to another numeric base and back, although I haven't tested it. You appear to be using base 104 which I don't really understand (oh I get it, you are using elements). Where does text come into this? Did you convert some text to a number and then change the base, or what?EditAfter messing around a bit, I discover that these functions are perhaps not best suited for your purpose. AutoIt is limited to 15 digit accuracy with numbers and these functions seem to adhere to that rule (in base 10). Therefore the type of message you could convert from text would be limited to very few characters - unless you convert each letter separately and concatenate. The code gets more complicated..A typical ascii character requires 3 decimal digits.On a side note, you can easily convert long strings to hex and back. Edited August 21, 2012 by czardas operator64 ArrayWorkshop
nullschritt Posted August 21, 2012 Author Posted August 21, 2012 (edited) Basically what you have here is code to convert from decimal to another numeric base and back, although I haven't tested it. You appear to be using base 104 which I don't really understand (oh I get it, you are using elements). Where does text come into this? Did you convert some text to a number and then change the base, or what? Edit After messing around a bit, I discover that these functions are perhaps not best suited for your purpose. AutoIt is limited to 15 digit accuracy with numbers and these functions seem to adhere to that rule (in base 10). Therefore the type of message you could convert from text would be limited to very few characters - unless you convert each letter separately and concatenate. The code gets more complicated..A typical ascii character requires 3 decimal digits. On a side note, you can easily convert long strings to hex and back. This what I am doing to convert. $text = StringSplit($text, '') $number = '' for $i=1 to $text[0] $number &= _Base(AscW($text[$i]), $base104) Next I'm not understanding.... perhaps? Should I not be able to turn the _dec back into the unicode number? then use chrw() on it to turn it back to the original character? And it's part of a proof of concept project, so thank you for telling me I can convert to hex and back, but I already know this. Am I maybe not understanding why it is so difficult to undo it ? :/ This what I had got so far trying for the reverse $string = StringSplit($string, "") $text = "" for $i=1 to $string[0] step 2 $text &= _dec($string[$i]&$string[$i+1], $base104) Next Edited August 21, 2012 by nullschritt
AZJIO Posted August 21, 2012 Posted August 21, 2012 (edited) expandcollapse popupGlobal $base104 = "H¦,He,Li,Be,B¦,C¦,N¦,O¦,F¦,Ne,Na,Mg,Al,Si,P¦,S¦,Cl,Ar,K¦,Ca,Sc,Ti,Cr,Mn,Fe,Co,Ni,Cu,Zn,Ga,Ge,As,Se,Br,Kr,Rb,Sr,Y¦,Zr,Nb,Mo,Tc,Ru,Rh,Pd,Ag,Cd,In,Sn,Sb,Te,I¦,Xe,Cs,Ba,La,Ce,Pr,Nd,Pm,Sm,Eu,Gd,Tb,Dy,Ho,Er,Tm,Yb,Lu,Hf,Ta,W¦,Re,Os,Ir,Pt,Au,Hg,Tl,Pb,Bi,Po,At,Rn,Fr,Ra,Ac,Th,Pa,U¦,Np,Pu,Am,Cm,Bk,Cf,Es,Fm,Md,No,Bh,Rg,Fl" $Z = _Base(305664, $base104) MsgBox(0, 'Сообщение', $Z) MsgBox(0, 'Сообщение', _Dec($Z, $base104)) Func _Base($iDecNumber, $sChar) Local $aBase = StringSplit($sChar, ",") Local $iBase = $aBase[0] Local $iLen = Int(Log($iDecNumber) / Log($iBase)) + 1 Dim $iUnit[$iLen + 1] Local $iReturn Local $iTemp = $iDecNumber If $aBase[0] <> $iBase Then SetError(1) Return -1 EndIf If $iDecNumber = 0 Then Return $aBase[1] For $i = 1 To $iLen For $i2 = 1 To $i - 1 $iTemp = $iTemp / $iBase Next $iUnit[$i] = $aBase[Mod($iTemp, $iBase) + 1] $iTemp = $iDecNumber Next For $i = 1 To $iLen $iReturn = $iUnit[$i] & $iReturn Next Return $iReturn EndFunc Func _Dec($iNumber, $sSymbol) Local $i, $iPos, $iReturn, $Len, $n $sSymbol &= "," $Len = StringLen($sSymbol)/3 If $Len < 2 Then Return SetError(1) $iNumber=StringTrimRight(StringRegExpReplace($iNumber, '(..)', '1,'), 1) $n=StringSplit($iNumber, ',') For $i = 1 To $n[0] $iPos = (StringInStr($sSymbol, $n[$i])+2) / 3 If Not $iPos Then Return SetError(2) $iReturn += ($iPos-1)*$Len^($n[0]-$i) Next Return $iReturn EndFunc Edited August 21, 2012 by AZJIO My other projects or all
czardas Posted August 21, 2012 Posted August 21, 2012 (edited) The problem is that you need to pad the numeric representation of each character with zeros, otherwise it is impossible to convert back. You are using unicode, so the largest possible numeric value would be 0xFFFF which is greater than 104^2. This implies that using base 104 requires at least three digits (six characters) to represent one unicode character. Here's how to do it: expandcollapse popup#include <Array.au3> Global $base104 = "H¦,He,Li,Be,B¦,C¦,N¦,O¦,F¦,Ne,Na,Mg,Al,Si,P¦,S¦,Cl,Ar,K¦,Ca,Sc,Ti,Cr,Mn,Fe,Co,Ni,Cu,Zn,Ga,Ge,As,Se,Br,Kr,Rb,Sr,Y¦,Zr,Nb,Mo,Tc,Ru,Rh,Pd,Ag,Cd,In,Sn,Sb,Te,I¦,Xe,Cs,Ba,La,Ce,Pr,Nd,Pm,Sm,Eu,Gd,Tb,Dy,Ho,Er,Tm,Yb,Lu,Hf,Ta,W¦,Re,Os,Ir,Pt,Au,Hg,Tl,Pb,Bi,Po,At,Rn,Fr,Ra,Ac,Th,Pa,U¦,Np,Pu,Am,Cm,Bk,Cf,Es,Fm,Md,No,Bh,Rg,Fl" $text = "Hello World" ; Convert to base 104 $text = StringSplit($text, '') $number = '' For $i=1 to $text[0] $nTemp = _Base(AscW($text[$i]), $base104) While StringLen($nTemp) < 6 $nTemp = "H¦" & $nTemp WEnd $number &= $nTemp Next MsgBox(0, "", $number) ; Convert back to text $aTemp = _StringEqualSplit($number, 6) ; Split to $base104 characters If @error Then Exit $ret = "" For $i = 0 To UBound($aTemp) -1 $ret &= ChrW(_Dec($aTemp[$i], $base104)) Next MsgBox(0, "", $ret) Func _StringEqualSplit($sString, $iNumChars) If (Not IsString($sString)) Or $sString = "" Then Return SetError(1, 0, 0) If (Not IsInt($iNumChars)) Or $iNumChars < 1 Then Return SetError(2, 0, 0) Return StringRegExp($sString, "(?s).{1," & $iNumChars & "}", 3) EndFunc Func _Base($iDecNumber, $sChar) Local $aBase = StringSplit($sChar, ",") Local $iBase = $aBase[0] Local $iLen = Int(Log($iDecNumber) / Log($iBase)) + 1 Dim $iUnit[$iLen + 1] Local $iReturn Local $iTemp = $iDecNumber If $aBase[0] <> $iBase Then SetError(1) Return -1 EndIf If $iDecNumber = 0 Then Return $aBase[1] For $i = 1 To $iLen For $i2 = 1 To $i - 1 $iTemp = $iTemp / $iBase Next $iUnit[$i] = $aBase[Mod($iTemp, $iBase) + 1] $iTemp = $iDecNumber Next For $i = 1 To $iLen $iReturn = $iUnit[$i] & $iReturn Next Return $iReturn EndFunc ;==>_Base Func _Dec($iNumber, $sChar) Local $iReturn Local $aBase = StringSplit($sChar, ",") Local $iBase = $aBase[0] Local $aTemp = StringRegExp($iNumber, "[a-zA-Z0-9:+¦/]{" & StringLen($aBase[1]) & "}", 3) For $i = 0 To UBound($aTemp) - 1 $iReturn += ($iBase ^ $i) * (_ArraySearch($aBase, $aTemp[UBound($aTemp) - 1 - $i], 0, 0, 1) - 1) Next Return $iReturn EndFunc ;==>_Dec If you were to use ASCII, then you could get away with using just 2 base104 digits (4 characters) to represent each ASCII character. Edited August 21, 2012 by czardas operator64 ArrayWorkshop
nullschritt Posted August 21, 2012 Author Posted August 21, 2012 The problem is that you need to pad the numeric representation of each character with zeros, otherwise it is impossible to convert back. You are using unicode, so the largest possible numeric value would be 0xFFFF which is greater than 104^2. This implies that using base 104 requires at least three digits (six characters) to represent one unicode character. Here's how to do it: expandcollapse popup#include <Array.au3> Global $base104 = "H¦,He,Li,Be,B¦,C¦,N¦,O¦,F¦,Ne,Na,Mg,Al,Si,P¦,S¦,Cl,Ar,K¦,Ca,Sc,Ti,Cr,Mn,Fe,Co,Ni,Cu,Zn,Ga,Ge,As,Se,Br,Kr,Rb,Sr,Y¦,Zr,Nb,Mo,Tc,Ru,Rh,Pd,Ag,Cd,In,Sn,Sb,Te,I¦,Xe,Cs,Ba,La,Ce,Pr,Nd,Pm,Sm,Eu,Gd,Tb,Dy,Ho,Er,Tm,Yb,Lu,Hf,Ta,W¦,Re,Os,Ir,Pt,Au,Hg,Tl,Pb,Bi,Po,At,Rn,Fr,Ra,Ac,Th,Pa,U¦,Np,Pu,Am,Cm,Bk,Cf,Es,Fm,Md,No,Bh,Rg,Fl" $text = "Hello World" ; Convert to base 104 $text = StringSplit($text, '') $number = '' For $i=1 to $text[0] $nTemp = _Base(AscW($text[$i]), $base104) While StringLen($nTemp) < 6 $nTemp = "H¦" & $nTemp WEnd $number &= $nTemp Next MsgBox(0, "", $number) ; Convert back to text $aTemp = _StringEqualSplit($number, 6) ; Split to $base104 characters If @error Then Exit $ret = "" For $i = 0 To UBound($aTemp) -1 $ret &= ChrW(_Dec($aTemp[$i], $base104)) Next MsgBox(0, "", $ret) Func _StringEqualSplit($sString, $iNumChars) If (Not IsString($sString)) Or $sString = "" Then Return SetError(1, 0, 0) If (Not IsInt($iNumChars)) Or $iNumChars < 1 Then Return SetError(2, 0, 0) Return StringRegExp($sString, "(?s).{1," & $iNumChars & "}", 3) EndFunc Func _Base($iDecNumber, $sChar) Local $aBase = StringSplit($sChar, ",") Local $iBase = $aBase[0] Local $iLen = Int(Log($iDecNumber) / Log($iBase)) + 1 Dim $iUnit[$iLen + 1] Local $iReturn Local $iTemp = $iDecNumber If $aBase[0] <> $iBase Then SetError(1) Return -1 EndIf If $iDecNumber = 0 Then Return $aBase[1] For $i = 1 To $iLen For $i2 = 1 To $i - 1 $iTemp = $iTemp / $iBase Next $iUnit[$i] = $aBase[Mod($iTemp, $iBase) + 1] $iTemp = $iDecNumber Next For $i = 1 To $iLen $iReturn = $iUnit[$i] & $iReturn Next Return $iReturn EndFunc ;==>_Base Func _Dec($iNumber, $sChar) Local $iReturn Local $aBase = StringSplit($sChar, ",") Local $iBase = $aBase[0] Local $aTemp = StringRegExp($iNumber, "[a-zA-Z0-9:+¦/]{" & StringLen($aBase[1]) & "}", 3) For $i = 0 To UBound($aTemp) - 1 $iReturn += ($iBase ^ $i) * (_ArraySearch($aBase, $aTemp[UBound($aTemp) - 1 - $i], 0, 0, 1) - 1) Next Return $iReturn EndFunc ;==>_Dec If you were to use ASCII, then you could get away with using just 2 base104 digits (4 characters) to represent each ASCII character. Thanks this works perfectly!
czardas Posted August 21, 2012 Posted August 21, 2012 I found this kind of intriguing. One piece of advice: when you are attempting to produce a reversible, and complicated, process; it's a good idea to start with the last step in the process. Make sure that you can undo that last step before you write any more code. Working your way outwards from the middle often makes it easier to spot any potential problems with the method you are using before they occur. operator64 ArrayWorkshop
nullschritt Posted August 21, 2012 Author Posted August 21, 2012 (edited) I found this kind of intriguing. One piece of advice: when you are attempting to produce a reversible, and complicated, process; it's a good idea to start with the last step in the process. Make sure that you can undo that last step before you write any more code. Working your way outwards from the middle often makes it easier to spot any potential problems with the method you are using before they occur.Yes, I knew I was close, but missing some detail. When I was pouring over it I was, sleep deprived and intoxicated, so I got frustrated and gave up for a bit lol, but now that I have seen it, I understand how simple of a thing I was missing the whole time. Edited August 21, 2012 by nullschritt
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now