AHK v2 --- Ersatzfunktionen

Veröffentliche deine funktionierenden Skripte und Funktionen

Moderator: jNizM

User avatar
Holle
Posts: 187
Joined: 01 Oct 2013, 23:19

AHK v2 --- Ersatzfunktionen

19 Feb 2014, 09:48

Da in v2 nun auch "Format" entfällt habe ich eine Ersatzfunktion geschrieben. Diese scheint auf dem ersten Blick etwas aufgebläht, aber dafür kann die nicht nur hex und decimal, sondern ALLE Zahlensysteme umwandeln.
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
}
Edit: Wenn man oft Zahlen von Dezimal zu Hexadezimal (und umgekehrt) konvertiert, und bei Hexadezimalen Zahlen das "0x" am Anfang haben möchte kann man diese Zusatzfunktionen nutzen:

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)
}

Return to “Skripte und Funktionen”

Who is online

Users browsing this forum: No registered users and 12 guests