-
Notifications
You must be signed in to change notification settings - Fork 73
/
Copy pathbaseConvert.ahk
179 lines (178 loc) · 11.8 KB
/
baseConvert.ahk
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
; Number System Converter by Holle
; http://www.autohotkey.com/forum/viewtopic.php?t=56135
; Some "names" for the number systems will be accepted such as decimal/dec/d/base10/dekal or
; binary/bin/digital/dual/di/b/base2
; Use can use the names/shortcuts or the "base", like "base10" for decimal or "base2" for binary.
baseConvert(value, from, to) ;the function baseConvert()
{
if !(value and from and to) ;if mising data...
{
MsgBox, 4096 , , Missing Parameter! `n`nUse: baseConvert("Value", "From", "To") `n`nExample: `nbaseConvert("55", "dec", "hex")
Exit
} ;else ....
;some names for number systems
base2 = Base2|Binary|Bin|Digital|Binär|Dual|Di|B
base3 = Base3|Ternary|Triple|Trial|Ternär
base4 = Base4|Quaternary|Quater|Tetral|Quaternär
base5 = Base5|Quinary|Pental|Quinär
base6 = Base6|Senary|Hexal|Senär
base7 = Base7|Septenary|Peptal|Heptal
base8 = Base8|Octal|Oktal|Oct|Okt|O
base9 = Base9|Nonary|Nonal|Enneal
base10 = Base10|Decimal|Dezimal|Denär|Dekal|Dec|Dez|D
base11 = Base11|Undenary|Monodecimal|Monodezimal|Hendekal
base12 = Base12|Duodecimal|Dedezimal|Dodekal
base13 = Base13|Tridecimal|Tridezimal|Triskaidekal
base14 = Base14|Tetradecimal|Tetradezimal|Tetrakaidekal
base15 = Base15|Pentadecimal|Pentadezimal|Pentakaidekal
base16 = Base16|Hexadecimal|Hexadezimal|Hektakaidekal|Hex|H
base17 = Base17|Peptaldecimal|Peptaldezimal|Heptakaidekal
base18 = Base18|Octaldecimal|Oktaldezimal|Octakaidekal|Oktakaidekal
base19 = Base19|Nonarydecimal|Nonaldezimal|Enneakaidekal
base20 = Base20|Vigesimal|Eikosal
base30 = Base30|Triakontal
base40 = Base40|Tettarakontal
base50 = Base50|Pentekontal
base60 = Base60|Sexagesimal|Hektakontal
StringReplace, value_form, value,(,,all
StringReplace, value_form, value_form ,),, all ;if value is integer or letter when...
if value_form is not Alnum ;...parenthesis are removed
{ ; if not...
MsgBox, 4096 , , Error! `n`nOnly alphanumeric Symbols will be accepted!
Exit
} ;------------------------------------------------------------------------------------
if (InStr(from, "base")) ;if the word "base" is in "from"...
{
StringTrimLeft, base_check, from, 4 ;...then cut "base" to have ONLY the number
if base_check is not Integer ;if "from" not integer now
{
MsgBox, 4096 , , Unknown Number System! `n`nUse Base + Number (example: Base16), `nor the name/shortcut (example: "Hexadecimal" or "Hex")
Exit
}
else ;else replace the value from "from"
from := base_check ;with the number in base_check
} ;------------------------------------------------------------------------------------
if (InStr(to, "base")) ;the same as above again for the destination number system
{
StringTrimLeft, base_check, to, 4
if base_check is not Integer
{
MsgBox, 4096 , , Unknown Number System! `n`nUse Base + Number (example: Base16), `nor the name/shortcut (example: "Hexadecimal" or "Hex")
Exit
}
else
to := base_check
} ;---------------------------------------------------------------------------------
base_loop := 1
loop, 60 ;check in a loop from 2 to 60 if the names from
{ ;the source / destination number system is in the Variable "base.."
if from is Integer ;if "from" is integer...
if to is Integer ;and "to" too...
Break ;...cancel the loop
if (base_loop < 20) ;if base_loop < 20...
base_loop ++ ;...increase by 1
else ;else...
base_loop += 10 ;...increase by 10
if (base_loop > 60) ;and if more then 60 ...
Break ;...cancel the loop
base := base%base_loop%
loop parse, base, | ;split every base variable word by word
{
if (from = A_LoopField) ;if one of them identical with the name ...
from := base_loop ;...from the source number system then save the number in "from"
if (to = A_LoopField) ; ...the same for the destination number system
to := base_loop
}
}
if (from < 11) ;by source numer system to 10 (therefore Decimal)
if value is not Integer ;letters are not allowed
{ ;else exit
StringGetPos, seperator_1, base%from%, |, L1 ;position of the first seperator
StringGetPos, seperator_2, base%from%, |, L2 ;position of the second seperator...
StringMid, name_from, base%from%, (seperator_1 + 2), (seperator_2 - seperator_1 - 1)
MsgBox, 4096 , , Error! `nNo letters allowed in %name_from% system!
Exit
}
con_letter := "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;allowed letters
result_dec=
length := StrLen(value) ;count the characters
counter := 0
parenthesis := False ;no parenthesis yet
loop, %length% ;loop by any character from "value"
{
StringMid, char, value, (length + 1 - A_Index), 1 ;process "backwards" the value, character by character
if (char = ")") ;if there an right parenthesis ...
{ ; (notice, we work "backwards" at this time)
if parenthesis ;...although there was an right parenthesis before (without a left parenthesis) ...
{ ;...then exit
MsgBox, 4096 , , Error!`nOnly "simple" parenthesis will be accepted!`n`nExample:`n57AH6(45)(48)G2 = accepted`n57AH6((45)(48))G2 = NOT accepted!
Exit
}
parenthesis := True ;else memorize that we are between parenthesis now
Continue ;...cancel the rest from the loop and continue from begin
}
else if (char = "(") ;if there an right parenthesis ...
{ ; (notice, we work "backwards" at this time)
if !parenthesis ;...although there wasn´t a right parenthesis before...
{ ;...then exit
MsgBox, 4096 , , Error!`nOnly "simple" parenthesis will be accepted!`n`nExample:`n57AH6(45)(48)G2 = accepted`n57AH6((45)(48))G2 = NOT accepted!
Exit
}
parenthesis := False ;else memorize that we are NOT between parenthesis now
if !par_char ;if nothing between the parenthesis...
{ ;...then exit
MsgBox, 4096 , , Error! `n No value between parenthesis!
Exit
}
char := par_char ;else, all numbers between parenthesis are ONE character now
}
else if parenthesis ;we are between parenthesis at this time...
{
if char is not Integer ;...and there is some other than Integer, then cancel
{
MsgBox, 4096 , , Error! ´nBetween parenthesis only numbers will be accepted!
Exit
}
par_char := char . par_char ;else put every character between the parenthesis to ONE value
Continue ;notice, because we work backwards in this loop, the next number will put BEFORE the previous number, ...
}
else if char is Alpha ;if there a letter
{
StringGetPos, char_pos, con_letter, %char% ;then check th position from this letter in "con_letter"
StringReplace, char, char, %char%, %char_pos% ;and replace the letter with the position-number
char += 10 ;and add 10
if (char >= from)
{ ;if the number greater than the number system...
StringGetPos, seperator_1, base%from%, |, L1 ;...Example: 18 in hexadecimal system
StringGetPos, seperator_2, base%from%, |, L2 ;then exit
StringMid, name_from, base%from%, (seperator_1 + 2), (seperator_2 - seperator_1 - 1)
char := from - 10
StringMid, char, con_letter, %char%, 1
MsgBox, 4096 , , Error! `nOnly letters until "%char%" will be accepted in %name_from% system!
Exit
}
}
if (char >= from) ;is the character at this position isn´t a letter, but a number which is...
{ ;...greater than the number system, then exit
max_value := from - 1
MsgBox, 4096 , , Error! `nOnly values from 0-%max_value% will be accepted in base%from% system!
Exit
}
result_dec += char * (from**counter) ;convert source number system to decimale number system
counter ++ ;increase counter by one
}
if (to = 10) ;if decimale system the destination number system
Return %result_dec% ;then return the result
result= ;else convert it to destination number system
while (result_dec)
{
char := Mod(result_dec , to) ; first number from destination number system
if (char > 35) ;if it greater than 35...
char := "(" . char . ")" ;...put it between parenthesis
else if (char > 9) ;if it less than 36 , but greater than 9,
StringMid, char, con_letter, (char - 9), 1 ;...replace it with a letter
result := char . result ;combine the characters to the result
result_dec := Floor(result_dec / to) ;calculate the remain to continue the converting with this
}
Return %result% ;return result
}