Tags: PowerShell
Das Umrechnen von dezimalen in binäre oder hexadezimale Zahlen ist eine ebenso gängige Anforderung wie das Konvertieren von Zeichen und Strings in numerische Werte und zurück. PowerShell bietet dafür verschiedene Mittel.
Während etwa das Darstellen eines ASCII-Wertes als korrespondierendes Zeichen über simples Casting zu bewerkstelligen ist, erfordert das Umrechnen zwischen Zahlensystemen etwas mehr Aufwand.
Dezimal zu hexadezimal und umgekehrt
Bei dieser Operation nutzt man den Format-Operator, dem man mit Hilfe einer Formatierungszeichenkette mitteilt, wie er den Operanden auf der rechten Seite darstellen soll:
"{0:d}" -f 0x1A
In diesem Beispiel dient {0:d} als Platzhalter für den ersten Operanden von -f (also für 0x1A). Die Ausgabe erfolgt aufgrund der Formatierungsangabe "d" dezimal. Bei der Konvertierung in das dezimale System kann man aber auf die Formatangabe oder sogar ganz auf den Operator verzichten, weil es sich dabei um das vorgegebene Zahlensystem handelt:
"{0}" -f (0xA + 0xB)
bzw. gleich
0xA + 0xB
Das Ergebnis der zweiten Addition ist automatisch 21.
Umgekehrt ist es jedoch notwendig, PowerShell explizit anzuweisen, einen Wert hexadezimal darzustellen:
"{0:x}" - f 10
Dieser Befehl gibt die Zahl 10 als 0xa aus. Schreibt man in den Format-String ein großes 'X', dann ist das Ergebnis 0xA. Um beim obigen Beispiel der Addition zu bleiben, müsste man diese so notieren, um ein hexadezimales Ergebnis zu erhalten:
"{0:x}" -f (0xA + 0xB)
Will man mehrere Zahlen in einem Ausdruck umwandeln, dann benötigt man entsprechend viele Platzhalter:
"{0:x} und {1:x}" -f 29, 30
Das Ergebnis lautet hier "1d und 1e".
Alternativ zum Operator bietet sich die Verwendung der format-Methode an:
[String]::Format("{0:x}", 123)
Diese Variante hat aber keinen ersichtlichen Vorteil gegenüber dem Operator.
In binäre und oktale Zahlen konvertieren
Der Format-Operator kennt kein Muster, mit dem sich dezimale oder hexadezimale Zahlen binär oder oktal darstellen lassen. Neben ":x" und ":d" gibt es für Zahlen nur noch ":e" für die Exponential-Schreibweise. Daher muss man für diese Aufgabe die .NET-Klasse Convert und ihre Methode ToString bemühen.
Wenn man etwa das dezimale 128 im Binärformat ausgeben möchte, dann würde der entsprechende Befehl so aussehen:
[Convert]::ToString(128, 2)
Das zweite Argument des Funktionsaufrufs steht für die Zahlenbasis, in diesem Fall wäre das 2 für binär. Bei der Umwandlung einer Zahl in die oktale Repräsentation würde man hier 8 einsetzen:
[Convert]::ToString(0x80, 8)
Diese Methode könnte man auch einsetzen, um eine Zahl hexadezimal darzustellen, indem man als Zahlenbasis 16 angibt:
[Convert]::ToString(128, 16)
Der umgekehrte Weg von binär oder oktal zu dezimal führt über die Methode ToInt32 bzw. ToInt64:
[Convert]::ToInt32(100000, 2)
Die "2" als zweites Argument teilt der Funktion ToInt32 mit, dass die übergebene Zahl auf der Basis 2, also binär zu interpretieren ist. Entsprechend könnte man mit
[Convert]::ToInt32(200, 8)
die Oktalzahl 200 in dezimale Repräsentation überführen.
Zahl in Zeichen umwandeln
Hin und wieder stellt sich das Problem, dass man den ASCII-Wert eines Zeichens benötigt oder Zeichen anhand des ASCII-Werts ausgeben oder verändern muss. Während in Basic mit asc$ und chr$ dafür eigene Funktionen existieren, reicht in PowerShell dafür ein Cast:
[char] 65
gibt das Zeichen 'A' aus. In die umgekehrte Richtung muss man das Zeichen erst explizit vom Typ Char ausweisen, bevor man es in Int umwandeln kann:
[int] [char] 'A'
Möchte man über alle Zeichen eines Strings iterieren, um sie zu verändern, dann wandelt man diesen erst in ein Array um:
"Test".ToCharArray() | foreach{ ([int] $_ ) }
Dieser Befehl gibt den numerischen Wert jedes Zeichens im
String "Test" aus.
Täglich Know-how für IT-Pros mit unserem Newsletter
Ähnliche Beiträge
Weitere Links
1 Kommentar
Wie addiere ich folgende variable mit 0x40?
$a = 0x10 80
$b = $a + 0x40
-> Das gewuenschtes Ergebnis sollte 0x50 80 sein, jedoch erhalte ich "0x10 8164"
Koennen Sie mir dagen wie die richtige Addition lautet um das gewuenschte Ergebnis 0x50 80 zu erhalten?
Besten Dank!