2

I've tried to search but find only one post describing the same method I'm using to parse a JSON so was wondering if there is a better way of doing this.

I wrote a small function to generate a random passowrd and using a Json ACII table to definr which characters will be part of the password, I chose this approach as I want to print out spelling for the password as well.

What I have currently is this:

[string]$asciiJson = @"
[
    {"Index": "1","Number": "33","AsciiCode": "!","Phonetic": "Exclamation point","Type": "Symbol"},
    {"Index": "2","Number": "34","AsciiCode": "\"","Phonetic":"Double quotes","Type": "Symbol"},
    {"Index": "3","Number": "35","AsciiCode": "#","Phonetic": "Hash sign","Type": "Symbol"},
    {"Index": "4","Number": "36","AsciiCode": "$","Phonetic": "Dollar sign","Type": "Symbol"},
    {"Index": "5","Number": "37","AsciiCode": "%","Phonetic": "Percent sign","Type": "Symbol"},
    {"Index": "6","Number": "38","AsciiCode": "&","Phonetic": "Ampersand","Type": "Symbol"},
    {"Index": "7","Number": "39","AsciiCode": "'","Phonetic": "Single quote","Type": "Symbol"},
    {"Index": "8","Number": "40","AsciiCode": "(","Phonetic": "Opening parenthesis","Type": "Symbol"},
    {"Index": "9","Number": "41","AsciiCode": ")","Phonetic": "Closing parenthesis","Type": "Symbol"},
    {"Index": "10","Number": "42","AsciiCode": "*","Phonetic": "Asterisk","Type": "Symbol"},
    {"Index": "11","Number": "43","AsciiCode": "+","Phonetic": "Plus sign","Type": "Symbol"},
    {"Index": "12","Number": "44","AsciiCode": ",","Phonetic": "Comma","Type": "Symbol"},
    {"Index": "13","Number": "45","AsciiCode": "-","Phonetic": "Minus sign -Hyphen","Type": "Symbol"},
    {"Index": "14","Number": "46","AsciiCode": ".","Phonetic": "Period","Type": "Symbol"},
    {"Index": "15","Number": "47","AsciiCode": "/","Phonetic": "Slash","Type": "Symbol"},
    {"Index": "16","Number": "58","AsciiCode": ":","Phonetic": "Colon","Type": "Symbol"},
    {"Index": "17","Number": "59","AsciiCode": ";","Phonetic": "SemiColon","Type": "Symbol"},
    {"Index": "18","Number": "60","AsciiCode": "<","Phonetic": "Less than sign","Type": "Symbol"},
    {"Index": "19","Number": "61","AsciiCode": "=","Phonetic": "Equal sign","Type": "Symbol"},
    {"Index": "20","Number": "62","AsciiCode": ">","Phonetic": "Greater than sign","Type": "Symbol"},
    {"Index": "21","Number": "63","AsciiCode": "?","Phonetic": "Question mark","Type": "Symbol"},
    {"Index": "22","Number": "64","AsciiCode": "@","Phonetic": "At symbol","Type": "Symbol"},
    {"Index": "23","Number": "91","AsciiCode": "[","Phonetic": "Opening bracket","Type": "Symbol"},
    {"Index": "24","Number": "92","AsciiCode": "\\","Phonetic": "Backslash","Type": "Symbol"},
    {"Index": "25","Number": "93","AsciiCode": "]","Phonetic": "Closing bracket","Type": "Symbol"},
    {"Index": "26","Number": "94","AsciiCode": "^","Phonetic": "Caret - circumflex","Type": "Symbol"},
    {"Index": "27","Number": "95","AsciiCode": "_","Phonetic": "Underscore","Type": "Symbol"},
    {"Index": "29","Number": "123","AsciiCode": "{","Phonetic": "Opening brace","Type": "Symbol"},
    {"Index": "30","Number": "124","AsciiCode": "|","Phonetic": "Vertical bar","Type": "Symbol"},
    {"Index": "31","Number": "125","AsciiCode": "}","Phonetic": "Closing brace","Type": "Symbol"},
    {"Index": "33","Number": "65","AsciiCode": "A","Phonetic": "Alpha ","Type": "Capital Letter"},
    {"Index": "34","Number": "66","AsciiCode": "B","Phonetic": "Bravo ","Type": "Capital Letter"},
    {"Index": "35","Number": "67","AsciiCode": "C","Phonetic": "Charlie ","Type": "Capital Letter"},
    {"Index": "36","Number": "68","AsciiCode": "D","Phonetic": "Delta ","Type": "Capital Letter"},
    {"Index": "37","Number": "69","AsciiCode": "E","Phonetic": "Echo ","Type": "Capital Letter"},
    {"Index": "38","Number": "70","AsciiCode": "F","Phonetic": "Foxtrot ","Type": "Capital Letter"},
    {"Index": "39","Number": "71","AsciiCode": "G","Phonetic": "Golf ","Type": "Capital Letter"},
    {"Index": "40","Number": "72","AsciiCode": "H","Phonetic": "Hotel ","Type": "Capital Letter"},
    {"Index": "41","Number": "73","AsciiCode": "I","Phonetic": "India ","Type": "Capital Letter"},
    {"Index": "42","Number": "74","AsciiCode": "J","Phonetic": "Juliet ","Type": "Capital Letter"},
    {"Index": "43","Number": "75","AsciiCode": "K","Phonetic": "Kilo ","Type": "Capital Letter"},
    {"Index": "44","Number": "76","AsciiCode": "L","Phonetic": "Lima ","Type": "Capital Letter"},
    {"Index": "45","Number": "77","AsciiCode": "M","Phonetic": "Mike ","Type": "Capital Letter"},
    {"Index": "46","Number": "78","AsciiCode": "N","Phonetic": "November ","Type": "Capital Letter"},
    {"Index": "47","Number": "79","AsciiCode": "O","Phonetic": "Oscar ","Type": "Capital Letter"},
    {"Index": "48","Number": "80","AsciiCode": "P","Phonetic": "Papa ","Type": "Capital Letter"},
    {"Index": "49","Number": "81","AsciiCode": "Q","Phonetic": "Quebec ","Type": "Capital Letter"},
    {"Index": "50","Number": "82","AsciiCode": "R","Phonetic": "Romeo ","Type": "Capital Letter"},
    {"Index": "51","Number": "83","AsciiCode": "S","Phonetic": "Sierra ","Type": "Capital Letter"},
    {"Index": "52","Number": "84","AsciiCode": "T","Phonetic": "Tango ","Type": "Capital Letter"},
    {"Index": "53","Number": "85","AsciiCode": "U","Phonetic": "Uniform ","Type": "Capital Letter"},
    {"Index": "54","Number": "86","AsciiCode": "V","Phonetic": "Victor ","Type": "Capital Letter"},
    {"Index": "55","Number": "87","AsciiCode": "W","Phonetic": "Whiskey ","Type": "Capital Letter"},
    {"Index": "56","Number": "88","AsciiCode": "X","Phonetic": "X-Ray ","Type": "Capital Letter"},
    {"Index": "57","Number": "89","AsciiCode": "Y","Phonetic": "Yankee ","Type": "Capital Letter"},
    {"Index": "58","Number": "90","AsciiCode": "Z","Phonetic": "Zulu ","Type": "Capital Letter"},
    {"Index": "59","Number": "97","AsciiCode": "a","Phonetic": "Alpha ","Type": "Lowercase Letter"},
    {"Index": "60","Number": "98","AsciiCode": "b","Phonetic": "Bravo ","Type": "Lowercase Letter"},
    {"Index": "61","Number": "99","AsciiCode": "c","Phonetic": "Charlie ","Type": "Lowercase Letter"},
    {"Index": "62","Number": "100","AsciiCode": "d","Phonetic": "Delta ","Type": "Lowercase Letter"},
    {"Index": "63","Number": "101","AsciiCode": "e","Phonetic": "Echo ","Type": "Lowercase Letter"},
    {"Index": "64","Number": "102","AsciiCode": "f","Phonetic": "Foxtrot ","Type": "Lowercase Letter"},
    {"Index": "65","Number": "103","AsciiCode": "g","Phonetic": "Golf ","Type": "Lowercase Letter"},
    {"Index": "66","Number": "104","AsciiCode": "h","Phonetic": "Hotel ","Type": "Lowercase Letter"},
    {"Index": "67","Number": "105","AsciiCode": "i","Phonetic": "India ","Type": "Lowercase Letter"},
    {"Index": "68","Number": "106","AsciiCode": "j","Phonetic": "Juliet ","Type": "Lowercase Letter"},
    {"Index": "69","Number": "107","AsciiCode": "k","Phonetic": "Kilo ","Type": "Lowercase Letter"},
    {"Index": "70","Number": "108","AsciiCode": "l","Phonetic": "Lima ","Type": "Lowercase Letter"},
    {"Index": "71","Number": "109","AsciiCode": "m","Phonetic": "Mike ","Type": "Lowercase Letter"},
    {"Index": "72","Number": "110","AsciiCode": "n","Phonetic": "November ","Type": "Lowercase Letter"},
    {"Index": "73","Number": "111","AsciiCode": "o","Phonetic": "Oscar ","Type": "Lowercase Letter"},
    {"Index": "74","Number": "112","AsciiCode": "p","Phonetic": "Papa ","Type": "Lowercase Letter"},
    {"Index": "75","Number": "113","AsciiCode": "q","Phonetic": "Quebec ","Type": "Lowercase Letter"},
    {"Index": "76","Number": "114","AsciiCode": "r","Phonetic": "Romeo ","Type": "Lowercase Letter"},
    {"Index": "77","Number": "115","AsciiCode": "s","Phonetic": "Sierra ","Type": "Lowercase Letter"},
    {"Index": "78","Number": "116","AsciiCode": "t","Phonetic": "Tango ","Type": "Lowercase Letter"},
    {"Index": "79","Number": "117","AsciiCode": "u","Phonetic": "Uniform ","Type": "Lowercase Letter"},
    {"Index": "80","Number": "118","AsciiCode": "v","Phonetic": "Victor ","Type": "Lowercase Letter"},
    {"Index": "81","Number": "119","AsciiCode": "w","Phonetic": "Whiskey ","Type": "Lowercase Letter"},
    {"Index": "82","Number": "120","AsciiCode": "x","Phonetic": "X-Ray ","Type": "Lowercase Letter"},
    {"Index": "83","Number": "121","AsciiCode": "y","Phonetic": "Yankee ","Type": "Lowercase Letter"},
    {"Index": "84","Number": "122","AsciiCode": "z","Phonetic": "Zulu ","Type": "Lowercase Letter"},
    {"Index": "85","Number": "48","AsciiCode": "0","Phonetic": "Zero","Type": "Number"},
    {"Index": "86","Number": "49","AsciiCode": "1","Phonetic": "One","Type": "Number"},
    {"Index": "87","Number": "50","AsciiCode": "2","Phonetic": "Two","Type": "Number"},
    {"Index": "88","Number": "51","AsciiCode": "3","Phonetic": "Three","Type": "Number"},
    {"Index": "89","Number": "52","AsciiCode": "4","Phonetic": "Four","Type": "Number"},
    {"Index": "90","Number": "53","AsciiCode": "5","Phonetic": "Five","Type": "Number"},
    {"Index": "91","Number": "54","AsciiCode": "6","Phonetic": "Six","Type": "Number"},
    {"Index": "92","Number": "55","AsciiCode": "7","Phonetic": "Seven","Type": "Number"},
    {"Index": "93","Number": "56","AsciiCode": "8","Phonetic": "Eight","Type": "Number"},
    {"Index": "94","Number": "57","AsciiCode": "9","Phonetic": "Nine","Type": "Number"}
]
"@

This is the part where I generate the various characters table

        # Generate characters tables
    $charsTable = ConvertFrom-Json -InputObject $asciiJson
    $symbolsTable = $charsTable | Where-Object { $_.Type -eq 'Symbol' }
    $capitalLettersTable = $charsTable | Where-Object { $_.Type -eq 'Capital Letter' }
    $lowerCaseLettersTable = $charsTable | Where-Object { $_.Type -eq 'Lowercase Letter' }
    $digitsTable = $charsTable | Where-Object { $_.Type -eq 'Number' }

All works nicely just noticed when calling function from achild script the parsing part is rather slow so I was wondering if there is a better way to populate the various character tables.

I will admit I'm rather new to JSON so if there is a better way to do this I would be more than glad to hear it.

All in all I can live with the perfromance hit but if there is a way to optimize code why not.

Thanks in advance for any help/Feedback.

PsCustomObject
  • 115
  • 3
  • 9

2 Answers2

1

Why using JSON (JavaScript) at all and not keeping it in PowerShell Object Notation (PSON) format?

You might easily convert it to an PowerShell expression using the ConvertTo-Expression cmdlet:

PS C:\> $asciiJson | ConvertFrom-Json | ConvertTo-Expression -Expand 1
@(
        [PSCustomObject]@{'AsciiCode' = '!'; 'Index' = '1'; 'Number' = '33'; 'Phonetic' = 'Exclamation point'; 'Type' = 'Symbol'},
        [PSCustomObject]@{'AsciiCode' = '"'; 'Index' = '2'; 'Number' = '34'; 'Phonetic' = 'Double quotes'; 'Type' = 'Symbol'},
        [PSCustomObject]@{'AsciiCode' = '#'; 'Index' = '3'; 'Number' = '35'; 'Phonetic' = 'Hash sign'; 'Type' = 'Symbol'},
        [PSCustomObject]@{'AsciiCode' = '$'; 'Index' = '4'; 'Number' = '36'; 'Phonetic' = 'Dollar sign'; 'Type' = 'Symbol'},
        [PSCustomObject]@{'AsciiCode' = '%'; 'Index' = '5'; 'Number' = '37'; 'Phonetic' = 'Percent sign'; 'Type' = 'Symbol'},
...

Anyway, I think you are reinventing the wheel.
A PowerShell password generator with features different character sets (and excluding specific characters) can be found here: https://stackoverflow.com/a/37275209/1701026

iRon
  • 20,463
  • 10
  • 53
  • 79
  • Well just a correction I'm not reinventing but reinvented the wheel :P On a more serious note, I jused Javascript format as I took one Json as exampel and did not both to format it appropriately, I'm used to JS and honestly did not even notice. Thanks for the link as I said what I posted is just a snippet of a larger code base but I will have a look at what you posted. – PsCustomObject Apr 30 '18 at 13:03
0

A rather late second answer, but I hadn't finished my project yet...

Readability

You wrote "All in all, I can live with the performance hit but if there is a way to optimize code why not" would suggest that you not looking for improving the performance but more for something that can be easier read. To answer that:
Currently, there are a number of listing formats available with converters that let you import a list of object but each option has its for a source table like this:

  • JSON objects (using ConvertFrom-JSON) is mainly for complex objects but not handy for a listing objects (same goes for PSON objects, using the ConvertTo-Expression cmdlet I purposed).
  • You could put your listing in an XMLDocument and parse it using the standard PowerShell [XML] parser. But that isn't also easy to read because it is to verbose for this requirement.
  • You could also consider using a CSV list (using ConvertFrom-CSV), but that actually only support strings and in most cases the columns do not align which makes it also difficult to read.
  • In fact it would be nice if you could use the output from a Format-Table but there is no convertor available that can convert this back PowerShell objects, or...

'ConvertFrom-SourceTable' cmdlet

The 'ConvertFrom-SourceTable' cmdlet, I created, can actually convert most Format-Table outputs back to a list of objects. Besides it can handle datatypes other than strings. How? See: ConvertFrom-SourceTable -?.

Taking your $asciiJson list as an example and prettify it a little bit because I presume that you would actually like to handle the Index and Numberas numeric values and maybe even format the ascii number as a hex number. To further show it capabilities I changed the AsciiCode column to a character column using [Char] (shorthand for [Char]Char, or if you wish; [Char]AsciiCode) which actually also supersedes the number column with e.g.: [Int]$AsciiTable[0].Char:

$AsciiTable | Select -Property `
    @{Name='Index'; Expression = {[Int]$_.Index}},
    @{Name='Number'; Expression = {"  0x{0:X2}" -f [Int]$_.Number}},
    @{Name='[Char]'; Expression = {$_.AsciiCode}},
    Phonetic,
    Type | Format-Table

Now simply put the result in a string (or in your case, a here-string as it contains quotes):

$AsciiTable = ConvertFrom-SourceTable @'
Index Number [Char] Phonetic            Type
----- ------ ------ --------            ----
    1   0x21 !      Exclamation point   Symbol
    2   0x22 "      Double quotes       Symbol
    3   0x23 #      Hash sign           Symbol
    4   0x24 $      Dollar sign         Symbol
    5   0x25 %      Percent sign        Symbol
    6   0x26 &      Ampersand           Symbol
    7   0x27 '      Single quote        Symbol
    8   0x28 (      Opening parenthesis Symbol
    9   0x29 )      Closing parenthesis Symbol
   10   0x2A *      Asterisk            Symbol
   11   0x2B +      Plus sign           Symbol
   12   0x2C ,      Comma               Symbol
   13   0x2D -      Minus sign -Hyphen  Symbol
   14   0x2E .      Period              Symbol
   15   0x2F /      Slash               Symbol
   16   0x3A :      Colon               Symbol
   17   0x3B ;      SemiColon           Symbol
   18   0x3C <      Less than sign      Symbol
   19   0x3D =      Equal sign          Symbol
   20   0x3E >      Greater than sign   Symbol
   21   0x3F ?      Question mark       Symbol
   22   0x40 @      At symbol           Symbol
   23   0x5B [      Opening bracket     Symbol
   24   0x5C \      Backslash           Symbol
   25   0x5D ]      Closing bracket     Symbol
   26   0x5E ^      Caret - circumflex  Symbol
   27   0x5F _      Underscore          Symbol
   29   0x7B {      Opening brace       Symbol
   30   0x7C |      Vertical bar        Symbol
   31   0x7D }      Closing brace       Symbol
   33   0x41 A      Alpha               Capital Letter
   34   0x42 B      Bravo               Capital Letter
   35   0x43 C      Charlie             Capital Letter
   36   0x44 D      Delta               Capital Letter
   37   0x45 E      Echo                Capital Letter
   38   0x46 F      Foxtrot             Capital Letter
   39   0x47 G      Golf                Capital Letter
   40   0x48 H      Hotel               Capital Letter
   41   0x49 I      India               Capital Letter
   42   0x4A J      Juliet              Capital Letter
   43   0x4B K      Kilo                Capital Letter
   44   0x4C L      Lima                Capital Letter
   45   0x4D M      Mike                Capital Letter
   46   0x4E N      November            Capital Letter
   47   0x4F O      Oscar               Capital Letter
   48   0x50 P      Papa                Capital Letter
   49   0x51 Q      Quebec              Capital Letter
   50   0x52 R      Romeo               Capital Letter
   51   0x53 S      Sierra              Capital Letter
   52   0x54 T      Tango               Capital Letter
   53   0x55 U      Uniform             Capital Letter
   54   0x56 V      Victor              Capital Letter
   55   0x57 W      Whiskey             Capital Letter
   56   0x58 X      X-Ray               Capital Letter
   57   0x59 Y      Yankee              Capital Letter
   58   0x5A Z      Zulu                Capital Letter
   59   0x61 a      Alpha               Lowercase Letter
   60   0x62 b      Bravo               Lowercase Letter
   61   0x63 c      Charlie             Lowercase Letter
   62   0x64 d      Delta               Lowercase Letter
   63   0x65 e      Echo                Lowercase Letter
   64   0x66 f      Foxtrot             Lowercase Letter
   65   0x67 g      Golf                Lowercase Letter
   66   0x68 h      Hotel               Lowercase Letter
   67   0x69 i      India               Lowercase Letter
   68   0x6A j      Juliet              Lowercase Letter
   69   0x6B k      Kilo                Lowercase Letter
   70   0x6C l      Lima                Lowercase Letter
   71   0x6D m      Mike                Lowercase Letter
   72   0x6E n      November            Lowercase Letter
   73   0x6F o      Oscar               Lowercase Letter
   74   0x70 p      Papa                Lowercase Letter
   75   0x71 q      Quebec              Lowercase Letter
   76   0x72 r      Romeo               Lowercase Letter
   77   0x73 s      Sierra              Lowercase Letter
   78   0x74 t      Tango               Lowercase Letter
   79   0x75 u      Uniform             Lowercase Letter
   80   0x76 v      Victor              Lowercase Letter
   81   0x77 w      Whiskey             Lowercase Letter
   82   0x78 x      X-Ray               Lowercase Letter
   83   0x79 y      Yankee              Lowercase Letter
   84   0x7A z      Zulu                Lowercase Letter
   85   0x30 0      Zero                Number
   86   0x31 1      One                 Number
   87   0x32 2      Two                 Number
   88   0x33 3      Three               Number
   89   0x34 4      Four                Number
   90   0x35 5      Five                Number
   91   0x36 6      Six                 Number
   92   0x37 7      Seven               Number
   93   0x38 8      Eight               Number
   94   0x39 9      Nine                Number
'@

Proving that it works:

PS C:\> $AsciiTable | Where {$_.Type -eq "Number"} | Format-Table

Type   Number Phonetic Index Char
----   ------ -------- ----- ----
Number     48 Zero        85    0
Number     49 One         86    1
Number     50 Two         87    2
Number     51 Three       88    3
Number     52 Four        89    4
Number     53 Five        90    5
Number     54 Six         91    6
Number     55 Seven       92    7
Number     56 Eight       93    8
Number     57 Nine        94    9

The ConvertFrom-SourceTable cmdlet is available for download at the PowerShell Gallery and the source code from the GitHub iRon7/ConvertFrom-SourceTable repository.

iRon
  • 20,463
  • 10
  • 53
  • 79