Hex conversion of GUID removes Zeros? - powershell

I have a script that takes the hex value of a GUID and converts to a GUID. However it is removing zeros for eg. this is my output. And the reg reads for the hex values.
$GUIDLocal1 = (Get-ItemProperty "$Reg\Common Api")."UniqueID"
$GUIDLocal2 = (Get-ItemProperty "$Reg\Test\Common Api")."UniqueID"
# This is not code below just info
$GUIDLocal1 is 54 171 225 63 61 204 14 79 168 61 49 246 193 140 121 152
$GUIdlocal2 is 54 171 225 63 61 204 14 79 168 61 49 246 193 140 121 152
ID in Database is 36ABE13F3DCC0E4FA83D31F6C18C7998
$guidinhex 36ABE13F3DCCE4FA83D31F6C18C7998
$guidinhex2 36ABE13F3DCCE4FA83D31F6C18C7998
# This is not code above just info
I am using this code for the conversion
$guidinHex = [string]::Empty
$guidinHex2 = [string]::Empty
$GUIDLocal1 | % { $guidInHEX += '{0:X}' -f [int]$_ }
$GUIDLocal2 | % { $guidInHEX2 += '{0:X}' -f [int]$_ }
ID is GUID with all {, }, and - removed for ease of view.
$GUIDLocal1 and $GUIDLocal2 is the hex value in registry.
I then use the code above to convert ($GUIDLocal1 and $GUIDLocal2 is the values guidinhex / 2).
The conversion works, but if there is a zero it strips it out as you can see above - this machine the GUID actually matches the reg values but my conversion is skewing the result I just need to know why and how not to have the conversion remove the Zero / s.
I thought adding [int] would help but to no avail.

The -f (format) operator lets you format a numeric value as a hexadecimal string with leading zeros. The format specification is {0:Xn} or {0:xn}, where n is the number of digits desired in the string output (padded with zeros if needed). Uppercase X or lowercase x specifies whether you want the hex values A through F to be uppercase or lowercase. Examples:
"{0:X2}" -f 15 # outputs string 0F
"{0:X3}" -f 27 # outputs string 01B
"{0:x4}" -f 254 # outputs string 00fe
...and so forth. Documentation here:
https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#XFormatString

Related

Powershell - [DateTime]::TryParseExact, two apparently identical strings, one works the other doesn't [duplicate]

This question already has answers here:
Unable to convert a string to an integer variable from DateTaken attribute on a JPG file
(2 answers)
Debugging PowerShell, two apparent identical values do not behave the same. How to find the difference [duplicate]
(1 answer)
Closed 1 year ago.
In powershell I have a date that I expect is a string and another that I created for debugging purposes which is a string.
function ParseDate {
param
(
$inputDate #when debugging this outputs - 04/11/2021 23:00
)
$date = "04/11/2021 23:00" #hard coded for debugging
$parsedDate = [DateTime]::MinValue;
# $date here, which I had for debugging, $inputDate will fail for parse
$parsedSuccessfully = [DateTime]::TryParseExact($date, "dd/MM/yyyy HH:mm", $null, [System.Globalization.DateTimeStyles]::None, [ref] $parsedDate);
return $parsedDate
}
If I parse the hardcoded date ($date) then it works fine, but if I parse the $inputDate it fails and $parsedSuccessfully will be false.
If I output the GetType() on both objects then it returns the same type -
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
Is there any way to tell what the difference is between the inputDate and hard coded date as something must be different as one works and the other does not.
See this answer here - https://stackoverflow.com/a/67228497/440760
Yes this was also my question!
Essentially use write-host( $tmp.ToCharArray() | % { [int] $_ }) to show the text in hex. This clearly shows that there are differences.
In my case -
8206 48 52 47 8206 49 49 47 8206 50 48 50 49 32 8207 8206 49 51 58 49 57 (didn't work)
AND
48 52 47 49 49 47 50 48 50 49 32 49 51 58 49 57 (worked).
The extra chars are BSTR which can be removed using
$formattedDateString = $value -replace '[^\p{L}\p{Nd}\:\/\ ]', ''

Spliting an emoji sequence in powershell

I have a text box that will be filled with emoji only. No spaces or characters of any kind. I need to split these emoji in order to identify them. This is what I have tried:
function emoji_to_unicode(){
foreach ($emoji in $textbox.Text) {
$unicode = [System.Text.Encoding]::Unicode.GetBytes($emoji)
Write-Host $unicode
}
}
Instead of printing the bytes one by one, the loop is running just once, printing the codes of all the emoji joined together. It's like all the emoji was a single item. I tested with 6 emoji, and instead of getting this:
61 216 7 222
61 216 67 222
61 216 10 222
61 216 28 222
61 216 86 220
60 216 174 223
I'm getting this:
61 216 7 222 61 216 67 222 61 216 10 222 61 216 28 222 61 216 86 220 60 216 174 223
What am I missing?
A string is just one element. You want to change it to a character array.
foreach ($i in 'hithere') { $i }
hithere
foreach ($i in [char[]]'hithere') { $i }
h
i
t
h
e
r
e
Hmm this doesn't work well. These code points are pretty high, U+1F600 (32-bit), etc
foreach ($i in [char[]]'😀😁😂😃😄😅😆') { $i }
ïżœ # 16 bit surrogate pairs?
ïżœ
ïżœ
ïżœ
ïżœ
ïżœ
ïżœ
ïżœ
ïżœ
ïżœ
ïżœ
ïżœ
ïżœ
ïżœ
Hmm ok, add every pair. Here's another way to do it using https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Surrogates (or just use ConvertToUTF32($emoji, 0) )
$emojis = '😀😁😂😃😄😅😆'
for ($i = 0; $i -lt $emojis.length; $i += 2) {
[System.Char]::IsHighSurrogate($emojis[$i])
0x10000 + ($emojis[$i] - 0xD800) * 0x400 + $emojis[$i+1] - 0xDC00 | % tostring x
# [system.char]::ConvertToUtf32($emojis,$i) | % tostring x # or
$emojis[$i] + $emojis[$i+1]
}
True
1f600
😀
True
1f601
😁
True
1f602
😂
True
1f603
😃
True
1f604
😄
True
1f605
😅
True
1f606
😆
Note that unicode in the Unicode.GetBytes() method call refers to utf16le encoding.
Chinese works.
[char[]]'ć—šïŒŒæ‚šć„œ'
旹

æ‚š
ć„œ
Here it is using utf32 encoding. All characters are 4 bytes long. Converting every 4 bytes into an int32 and printing them as hex.
$emoji = '😀😁😂😃😄😅😆'
$utf32 = [System.Text.Encoding]::utf32.GetBytes($emoji)
for($i = 0; $i -lt $utf32.count; $i += 4) {
$int32 = [bitconverter]::ToInt32($utf32[$i..($i+3)],0)
$int32 | % tostring x
}
1f600
1f601
1f602
1f603
1f604
1f605
1f606
Or going the other way from int32 to string. Simply casting the int32 to [char] does not work (have to add pairs of [char]'s). Script reference: https://www.powershellgallery.com/packages/Emojis/0.1/Content/Emojis.psm1
for ($i = 0x1f600; $i -le 0x1f606; $i++ ) { [System.Char]::ConvertFromUtf32($i) }
😀
😁
😂
😃
😄
😅
😆
See also How to encode 32-bit Unicode characters in a PowerShell string literal?
EDIT:
Powershell 7 has a nice enumeraterunes() method:
$emojis = '😀😁😂😃😄😅😆'
$emojis.enumeraterunes() | % value | % tostring x
1f600
1f601
1f602
1f603
1f604
1f605
1f606

Concatenation of Matlab strings

I want to make a Matlab function that takes two matrices A and B (of the same size) and combines them in a certain way to give an output that can be used in Latex - table.
I want the first row of the output matrix to consist of the first row of matrix A, with ampersands (&) in between them, and that ends with an double backslash.
The second row should be the first row of B with parentheses around them, and ampersands in between. And so on for the rest of A and B.
If I let A=rand(1,2), I could do this by using [num2str(A(1)), ' & ', num2str(A(2)),' \\'] and so on.
But I want to be able to make a function that does this for any size of the matrix A. I guess I have to make cell structures in some way. But how?
This could be one approach -
%// First off, make the "mixed" matrix of A and B
AB = zeros(size(A,1)*2,size(A,2));
AB(1:2:end) = A;
AB(2:2:end) = B;
%// Convert all numbers of AB to characters with ampersands separating them
AB_amp_backslash = num2str(AB,'%1d & ');
%// Remove the ending ampersands
AB_amp_backslash(:,end-1:end) = [];
%// Append the string ` \\` and make a cell array for the final output
ABcat_char = strcat(AB_amp_backslash,' \\');
ABcat_cell = cellstr(ABcat_char)
Sample run -
A =
183 163 116 50
161 77 107 91
150 124 56 46
B =
161 108 198 4
198 18 14 137
6 161 188 157
ABcat_cell =
'183 & 163 & 116 & 50 \\'
'161 & 108 & 198 & 4 \\'
'161 & 77 & 107 & 91 \\'
'198 & 18 & 14 & 137 \\'
'150 & 124 & 56 & 46 \\'
' 6 & 161 & 188 & 157 \\'
You can use sprintf, it will repeat the format spec as many times as required until all input variables are processed:
%combine both to one matrix
C=nan(size(A).*[2,1]);
C(1:2:end)=A;
C(2:2:end)=B;
%print
sprintf('%f & %f \\\\\n',C.')
The transpose (.') is required to fix the ordering.

Is default '\n' line terminator can be changed?

Is default '\n' Matlab line terminator can be changed? Can I use ',' instead of '\n'? Because the serial port that will be reading it is programmed to terminate when ',' is read.Is it possible?
Any answers are highly appreciated! Thanks in advance!
use eg:
ser = serial('COM1'); % establish connection between Matlab and COM1
set(ser, 'Terminator', 'CR'); % set communication string to end on ASCII 13
and replace 'CR' with ','
See
http://www.swarthmore.edu/NatSci/ceverba1/Class/e5/E5MatlabExamples.html
http://www.mathworks.co.uk/help/matlab/matlab_external/terminator.html
A simple string in matlab is not terminated by \n or \0 since it is a simple array of chars, as seen here:
>> a = string('Hello World')
Warning: string is obsolete and will be discontinued.
Use char instead.
a =
Hello World
>> double(a)
ans =
72 101 108 108 111 32 87 111 114 108 100
to add a \0 to the end simply use:
>> a(end+1)=0;
>> a
a =
Hello World
>> double(a) %the zero is there, but not printable as seen here
ans =
72 101 108 108 111 32 87 111 114 108 100 0

In Matlab, with an English text file, how to load the file and get a matrix as an ASCII encoding result?

Firstly it is a very simple example:
In a text file ('test1.txt'), the content is:
Formally, the
What I want to get is an array with the ASCII encoding result like:
dat_ascii = [70 111 114 109 97 108 108 121 44 32 116 104 101]
In the result, every char is translated to ASCII code, even space and common.
Now I have a text file like 10MB full with English text. I want to read it and translate every char to ASCII code and put them into a matrix (with every 4096 char per line, many lines).
How can I do this in Matlab?
You can easily convert every thing in ASCII with :
double, you just cast to double your string.
And to revert it, just do char
Example :
myStr = 'I have 2 apple.'
myStr =
I have 2 apple.
myASCII = double(myStr)
myASCII =
73 32 104 97 118 101 32 50 32 97 112 112 108 101 46
myChar = char(myASCII)
myChar =
I have 2 apple.
In order to read text file in MATLAB, you need to open the text file and read
>> filePtr = fopen('test1.txt')
and then use the file pointer to read the data and convert to ASCII values:
>> ASCIIValues = double(textscan(filePtr, '%c')); ASCIIValues{:}
Note: Use the appropriate formatting argument when you try to read a text file. In my case, I neglect all whitespaces. For documentation, read http://www.mathworks.com/help/matlab/ref/textscan.html