Ich habe das schon auf englisch verfasst, da ich diese Funktione später noch in´s englische Forum posten werde, aber da momentan noch ein v2-Bereich existiert poste ich das erstmal nur hier.
Bitte postet Kritik, Lob, Verbesserungsvorschläge, Korrekturen, usw.
Vielen Dank.
So, hier ist das Script:
Code: Select all
; =================================================================================
; | Format.ahk (by Holle)
; |
; | Date: 2014/02/19
; |
; | Syntax: Format(Value , From , To [,ErrorMsg])
; |
; | What does it do?
; | Format.ahk is able to convert every number systems.
; | Because we have only 35 chars (numbers 0-9 and letters A-Z) it is not possible to replace every value with letters,
; | but you can use parenthesis with the value inside, instead a letter.
; | from and to can be a number or "b/bin/binary","d/dec/decimal","h/x/hex/hexadecimal","o/oct/octal" or "base...".
; |
; | Examples:
; | Format("12345","d","h") --> convert the decimal number "12345" to the hexadecimal number "3039" (WITHOUT "0x" !!!)
; | Format("12F","16","10") --> convert the hexadecimal number "12F" to the decimal number "303"
; | Format("10000","b","Base20") --> convert the binary number "10000" to the Base20 number "G"
; | Format("12(40)F","Base45","dec") --> convert the Base45 number "12(40)F" to the decimal number "96990".
; | Because there is no letter for "40" it is embedded in parenthesis, instead replace with a letter.
; | Format("12(40)F","Base35","dec") --> returns "nothing", because there is a error. To find the error, use this:
; | Format("12(40)F","Base35","dec", ErrorMsg)
; | MsgBox %ErrorMsg% --> Only numbers from 0-34 are available! --> Value = "12(40)F"
; | OK, the Error is, that the embedded number "40" does not exist in Base35
; | (same like the letter "G" does not exist in Hexadecimal)
; |
; =================================================================================
Format(value, from, to, ByRef ErrorMsg:="") {
if (!value || !from || !to) , return (ErrorMsg:= 'Missing "' . SubStr((!value?', value':'') . (!from?', from':'') . (!to?', to':'') . '"',3))?'':''
from := SubStr(from,1,4)="base"?SubStr(from,5)+0:SubStr(from,1,1)="b"?2:SubStr(from,1,1)="o"?8:SubStr(from,1,1)="d"?10:(SubStr(from,1,1)="h")||(SubStr(from,1,1)="x")?16:from
if !(from~="^\s*[\+\-]?((0x[0-9A-Fa-f]+)|\d+)\s*$") , return (ErrorMsg:= 'Unknown format (from = "' . from . '")')?'':''
to := SubStr(to,1,4)="base"?SubStr(to,5)+0:SubStr(to,1,1)="b"?2:SubStr(to,1,1)="o"?8:SubStr(to,1,1)="d"?10:(SubStr(to,1,1)="h")||(SubStr(to,1,1)="x")?16:to
if !(to~="^\s*[\+\-]?((0x[0-9A-Fa-f]+)|\d+)\s*$") , return (ErrorMsg:= 'Unknown format (to = "' . to . '")')?'':''
value := (from=16)&&(SubStr(value,1,2)="0x")?SubStr(value,3):value ; cut prefix
if !(RegExReplace(value,"[\(\)]*","$1")~="^[[:alnum:]]*$") ; only AlNum is allowed ...and "()"
|| ((from < 11) && !(RegExReplace(value,"[\(\)]*","$1")~="^\s*[\+\-]?((0x[0-9A-Fa-f]+)|\d+)\s*$"))
return (ErrorMsg:= 'Value = "' value '", but only integer is possible, because "from is ' from '".')?'':''
con_letter := "ABCDEFGHIJKLMNOPQRSTUVWXYZ", result_dec := 0, length := StrLen(value), counter := 0, parenthesis := False
loop length {
char := SubStr(value, (length + 1 - A_Index), 1) ; calculate "backward" every char
if (char = ")") { ; remember, we calculate "backward"
if parenthesis , return (ErrorMsg:= 'Parenthesis inside parenthesis is not allowed. --> Value = "' value '"')?'':''
parenthesis := True ; inside parenthesis
Continue
}
else if (char = "(") { ; remember, we calculate "backward"
if !parenthesis , return (ErrorMsg:= 'Left parenthesis without right parenthesis! --> Value = "' value '"')?'':''
parenthesis := False , char := par_char ; outside parenthesis
if !par_char && (par_char != "0"), return (ErrorMsg:= 'Parenthesis without content! --> Value = "' value '"')?'':''
}
else if parenthesis { ; inside parenthesis...
if !(char~="^\s*[\+\-]?((0x[0-9A-Fa-f]+)|\d+)\s*$") , return (ErrorMsg:= 'Only integer is allowed inside parenthesis! --> Value = "' value '"')?'':''
par_char := char . par_char
Continue
}
else if (char~="^[[:alpha:]]*$") { ; char is a letter
char_pos := InStr(con_letter,char) ; check position in "con_letter"
StrReplace, char, %char%, %char%, %char_pos% ; replace letter with the position
char += 9 ; und add 9
if (char >= from) , return (ErrorMsg:= 'Only letters from A-' SubStr(con_letter,char-10,1) ' are available! --> Value = "' value '"')?'':''
}
char += 0 ; convert to integer
if (char >= from) , return (ErrorMsg:= 'Only numbers from 0-' from-1 ' are available! --> Value = "' value '"')?'':''
result_dec += char * (from**counter) , counter += 1 ; calculate from source to decimal
}
if (to = 10) , Return result_dec ; if destination = decimal
result := "" ; else calculate from decimal to destination system
while (result_dec)
char := Mod(result_dec , to)
, char := (char>35)?"(" char ")":(char>9)?SubStr(con_letter,(char-9),1):char
, result := char . result
, result_dec := Floor(result_dec / to)
return result
}
Code: Select all
hex2dec(value) { ; Hexadecimal to Decimal
; Example --> hex2dec("1A") = 26
return Format(value,16,10)
}
dec2hex(value,CutPrefix:=0) { ; Decimal to Hexadecimal
; Example 1 --> dec2hex(26) = 0x1A
; Example 2 --> dec2hex(26,1) = 1A (Prefix is cut)
return CutPrefix?Format(value,10,16):"0x" . Format(value,10,16)
}