Get Windows 32-bit formatted Time/Date in PowerShell - windows

Is there a PowerShell command for retrieving the current datetime as a value encoded in the Windows C Runtime 32-Bit Time/Date Format?

I am not aware of an already existing function for that. You can do it manually like this:
$date = Get-Date
[uint16]$encodedTime = (((($date.Hour) -shl 6) + $date.Minute) -shl 5) + $date.Second / 2
[uint16]$encodedDate = (((($date.Year - 1980) -shl 4) + $date.Month) -shl 5) + $date.Day
You can combine these values further, if needed:
[uint32]$encodedTimeDate = $encodedTime -shl 16 + $encodedDate
[uint32]$encodedDateTime = $encodedDate -shl 16 + $encodedTime

To complement stackprotector's excellent answer, I used his code to create two helper functions to convert to and -from a dos datetime value:
function ConvertTo-DosDateTime {
[CmdletBinding()]
param (
[Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[DateTime]$Date = (Get-Date)
)
# seconds are stored divided by 2
[uint16]$encodedTime = (((($Date.Hour) -shl 6) + $Date.Minute) -shl 5) + ($Date.Second -shr 1)
[uint16]$encodedDate = (((($Date.Year - 1980) -shl 4) + $Date.Month) -shl 5) + $Date.Day
([uint32]$encodedDate -shl 16) + $encodedTime
}
function ConvertFrom-DosDateTime {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
[uint32]$DosDate
)
# split the 4 bytes into a date and a time part
[uint32]$encodedDate = $DosDate -shr 16
[uint32]$encodedTime = $DosDate -band 0xffff
# shift and mask-off the relevant bits
$day = $encodedDate -band 0x1f # 5 bits (0-4)
$month = ($encodedDate -shr 5) -band 0xf # 4 bits (5-8)
$year = (($encodedDate -shr 9) -band 0x7f) + 1980 # 7 bits (9-15)
# same for the time part
$secs = ($encodedTime -band 0x1f) * 2 # 5 bits (0-4)
$mins = ($encodedTime -shr 5) -band 0x3f # 6 bits (5-10)
$hrs = ($encodedTime -shr 11) -band 0x1f # 5 bits (11-15)
# return as DateTime object
Get-Date -Year $year -Month $month -Day $day -Hour $hrs -Minute $mins -Second $secs -Millisecond 0
}
All credits to stackprotector of course.

Related

How to read the Base Framing Protocol of RFC6455?

My reference are:
Writing a WebSocket server in Java
Base Framing Protocol
Why the first byte 129 represent FIN, RSV1, RSV2, RSV3, and Opcode?
My expected result are:
The first byte is the FIN / 1 bit, RSV1 / 1 bit, RSV2 / 1 bit, RSV3 / 1 bit, Opcode / 1 bit, Mask / 1 bit. Total 9 bits.
The second byte is the Payload length. Total 7 bits.
My actual result are:
The first byte represent FIN, RSV1, RSV2, RSV3, and Opcode.
The second byte represent the Payload length.
Just to illustrate a bit.
First Byte:
Leftmost bit is the fin-bit rightmost 4 bits represents the opcode,
in this case 1=text
10000001
Second Byte:
Leftmost bit indicates if data is masked remaining seven indicate the length
10000000 here the lenght is zero
11111101 here the lenght is exactly 125
11111110 here the lenght indicator is 126 therefor the next two bytes will give you the length followed by four bytes for the mask-key
11111111 here the lenght indicator is 127 therefor the next eight bytes will give you the length followed by four bytes for the mask-key
After all this follows the masked payload.
ADDED 2021-07-19
To extract information like opcode and length, you have to apply some bit operations on the given bytes.
Below is an extraction from
https://github.com/napengam/phpWebSocketServer/blob/master/server/RFC6455.php to show how the server decodes a frame.
public function Decode($frame) {
// detect ping or pong frame, or fragments
$this->fin = ord($frame[0]) & 128;
$this->opcode = ord($frame[0]) & 15;
$length = ord($frame[1]) & 127;
if ($length <= 125) {
$moff = 2;
$poff = 6;
} else if ($length == 126) {
$l0 = ord($frame[2]) << 8;
$l1 = ord($frame[3]);
$length = ($l0 | $l1);
$moff = 4;
$poff = 8;
} else if ($length == 127) {
$l0 = ord($frame[2]) << 56;
$l1 = ord($frame[3]) << 48;
$l2 = ord($frame[4]) << 40;
$l3 = ord($frame[5]) << 32;
$l4 = ord($frame[6]) << 24;
$l5 = ord($frame[7]) << 16;
$l6 = ord($frame[8]) << 8;
$l7 = ord($frame[9]);
$length = ( $l0 | $l1 | $l2 | $l3 | $l4 | $l5 | $l6 | $l7);
$moff = 10;
$poff = 14;
}
$masks = substr($frame, $moff, 4);
$data = substr($frame, $poff, $length); // hgs 30.09.2016
$text = '';
$m0 = $masks[0];
$m1 = $masks[1];
$m2 = $masks[2];
$m3 = $masks[3];
for ($i = 0; $i < $length;) {
$text .= $data[$i++] ^ $m0;
if ($i < $length) {
$text .= $data[$i++] ^ $m1;
if ($i < $length) {
$text .= $data[$i++] ^ $m2;
if ($i < $length) {
$text .= $data[$i++] ^ $m3;
}
}
}
}
return $text;
}
In https://github.com/napengam/phpWebSocketServer/blob/master/phpClient/websocketCore.php you will find encode and decode for the client.

Numerical sequence of 1 2 4

I need help in providing an algorithm for a numerical sequence which should display a series of 1 2 4 and its consecutive summations.
e.g. If my input value is 20, it should display
1 2 4 8 9 11 15 16 18
Wherein
1 = 1
2 = 1 + 1
4 = 2 + 2
8 = 4 + 4
And the summation of 1 and 2 and 4 will repeat again starting with the present number which is 8 and so on..
9 = 8 + 1
11 = 9 + 2
15 = 11 + 4
16 = 15 + 1
18 = 16 + 2
As you can see, it should not proceed to 22 (18 + 4) since our sample input value is 20. I hope you guys get my point. I'm having a problem in designing the algorithms in the for loop. What I have now which is not working is
$input = 20;
for ($i = $i; $i < $input; $i = $i+$i) {
if($i==0){
$i = 4;
$i = $i - 3;
}elseif($i % 4 == 0){
$i = $i + 1;
}
print_r("this is \$i = $i<br><br>");
}
NOTE: Only one variable and one for loop is required, it will not be accepted if we use functions or arrays. Please help me, this is one of the most difficult problems I've encountered in PHP..
you can use the code
$input = 20;
$current = 1;
$val = 1;
while($val < $input){
print_r("this is \$val = $val\n");
$val = $val + $current;
$current = ($current == 4 ? 1 : $current*2);
}
see the online compiler
Since you have mentioned Only one variable and one for loop is required
Try this,
$input = 20;
for ($i = 1; $i < $input; $i) {
if($i>$input) break;
print_r("this is \$i = $i<br><br>");
$i=$i+1;
if($i>$input) break;
print_r("this is \$i = $i<br><br>");
$i=$i+2;
if($i>$input) break;
print_r("this is \$i = $i<br><br>");
$i=$i+4;
}
Online Compiler
def getSeq(n):
if n == 1:
return [1]
temp = [1]
seq = [ 1, 2, 4]
count, current, prev = 0, 0, 1
while True:
current = prev + seq[count]
if current > n:
break
prev = current
temp += [current]
count = (count + 1) % 3
return temp
print getSeq(20)
I'm pretty sure that this one is going to work
the case that we have to take care of is n == 1 and return a static result [1].
in other cases the second value is repeating circularly and adding up to previous value.
This Python solution should be implementable in any reasonable language:
limit = 20
n = 1 << 2
while n >> 2 < limit:
print(n >> 2)
n = (((n >> 2) + (2 ** (n & 3))) << 2) + ((n & 3) + 1) % 3
Perl Equivalent (using the style of for loop you expect):
$limit = 20;
for ($n = 1 << 2; $n >> 2 < $limit; $n = ((($n >> 2) + (2 ** ($n & 3))) << 2) + (($n & 3) + 1) % 3) {
print($n >> 2, "\n");
}
OUTPUT
1
2
4
8
9
11
15
16
18
EXPLANATION
The basic solution is this:
limit = 20
n = 1
i = 0
while n < limit:
print(n)
n = n + (2 ** i)
i = (i + 1) % 3
But we need to eliminate the extra variable i. Since i only cycles through 0, 1 and 2 we can store it in two bits. So we shift n up two bits and store the value for i in the lower two bits of n, adjusting the code accordingly.
Not only one variable and one for loop, no if statements either!

How to parse a time in years in QBasic

How to parse a time (month/date/year) in Microsoft QBasic, needed for testing.
s = 'PT1H28M26S'
I would like to get:
num_mins = 88
You can parse such a time string with the code below, but the real question is:
Who still uses QBasic in 2015!?
CLS
s$ = "PT1H28M26S"
' find the key characters in string
posP = INSTR(s$, "PT")
posH = INSTR(s$, "H")
posM = INSTR(s$, "M")
posS = INSTR(s$, "S")
' if one of values is zero, multiplying all will be zero
IF ((posP * posH * posM * posS) = 0) THEN
' one or more key characters are missing
nummins = -1
numsecs = -1
ELSE
' get values as string
sHour$ = MID$(s$, posP + 2, (posH - posP - 2))
sMin$ = MID$(s$, posH + 1, (posM - posH - 1))
sSec$ = MID$(s$, posM + 1, (posS - posM - 1))
' string to integer, so we can calculate
iHour = VAL(sHour$)
iMin = VAL(sMin$)
iSec = VAL(sSec$)
' calculate totals
nummins = (iHour * 60) + iMin
numsecs = (iHour * 60 * 60) + (iMin * 60) + iSec
END IF
' display results
PRINT "Number of minutes: "; nummins
PRINT "Number of seconds: "; numsecs
PRINT "QBasic in 2015! w00t?!"
Simpler way to grab minutes from string in qbasic
REM Simpler way to grab minutes from string in qbasic
S$ = "PT1H28M26S"
S$ = MID$(S$, 3) ' 1H28M26S
V = INSTR(S$, "H") ' position
H = VAL(LEFT$(S$, V - 1)) ' hours
S$ = MID$(S$, V + 1) ' 28M26S
V = INSTR(S$, "M") ' position
M = VAL(LEFT$(S$, V - 1)) ' minutes
PRINT "num_mins ="; H * 60 + M

Pyramid Number Algorithm

I want to generate a static pyramid like these:
1 2 4 8 16 32 64 128 64 32 16 8 4 2 1
1 2 4 8 16 32 64 32 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 4 2 1
1 2 4 2 1
1 2 1
1
with PHP, I already create this code :
<center>
<?php
$x1 = 1; $x2 = 128;
$str_tmp = "";
$cek = 0;
$start = 0;
for($i=0;$i<=7;$i++){
for($j=$i;$j<=13;$j++){
for($z=$i;$z<$i;$z++){
$str_tmp.= ("&nbsp") ;
}
if($x2==1){
$str_tmp.= $x2;
break;
}
if($cek==0){
$str_tmp.= $x1 . " ";
$x1 = $x1 * 2;
if($x1==$x2){
$cek = 1;
$x2 = $x2/2;
}
}if($cek==1){
$str_tmp.= $x1 . " ";
$x1 = $x1 /2;
}if($cek==1&&$x1<1){
break;
}
}
echo $str_tmp."</br>";
$str_tmp = "";
$x1 = 1;
$cek = 0;
}
?>
</center>
I think it's looks like too complicated. Do you guys have a better solution? I don't mind if you guys write the code with another language.
Thank You
Something like this?
echo "<div style=\"text-align: center;\">";
for ($l=7; $l>=0; $l--){
$str = "";
for ($p=-$l; $p<=$l; $p++)
$str .= (1 << ($l - abs($p))) . " ";
echo substr($str,0,-1) . ($l ? "<br>" : "");
}
echo "</div>";
Not as nicely formatted (no whitespace to center lines), but it works.
<?php
function pyramid($highest) {
$pyramid = array();
while($highest >= 1) {
$pyramid[$highest] = array();
$x = $highest;
$tmp = array();
while($x >= 1) {
array_push($tmp, $x);
$x = intval($x/2);
}
$line = array_reverse($tmp);
foreach(array_slice($tmp, 1) as $y) {
array_push($line, $y);
}
array_push($pyramid, $line);
$highest = intval($highest/2);
}
return $pyramid;
}
foreach(pyramid(128) as $line) {
foreach($line as $num) {
echo $num." ";
}
echo "<br>";
}
?>

convert 1mio Perl bitvector to .5 mio integer array

I have bitvector coming from the database of length 1 Mio with two bits
each representing one integer number for compressed storage:
the bit string : 10110001 from the database
array 2 3 0 1 needed for further processing
The current solution is:
my $bitstring =
$sth->fetchrow_array(); # has 2 bits / snp, need 2 convert to I
my $snp_no = 1000000;
for ( my $i = 0; $i <= $snp_no - 1; $i++ ) {
my $A2 = substr ($bitstring ,$j,2);
$j = $j + 2;
my $vec = Bit::Vector->new_Bin(32, $A2);
#bitArray->[$i] = $vec->to_Dec();
}
This does work but is is waaay too slow: to process one such vector take a second
and with thousands of them the processing will take hours.
does someone have an idea how this can be made faster?
If you start with the data "packed", use the following:
my #decode =
map [
($_ >> 6) & 3,
($_ >> 4) & 3,
($_ >> 2) & 3,
($_ >> 0) & 3,
],
0x00..0xFF;
my #nums = map #{ $decode[$_] }, unpack 'C*', $bytes;
For me, this takes about roughly 1.1s for 1,000,000 bytes, which is to say 1.1 microseconds per byte.
A specialized pure C solution takes about half the time.
use Inline C => <<'__EOI__';
void decode(AV* av, SV* sv) {
STRLEN len;
U8* p = (U8*)SvPVbyte(sv, len);
av_fill(av, len*4);
av_clear(av);
while (len--) {
av_push(av, newSViv(*p >> 6 ));
av_push(av, newSViv(*p >> 4 & 3));
av_push(av, newSViv(*p >> 2 & 3));
av_push(av, newSViv(*(p++) & 3));
}
}
__EOI__
decode(\my #nums, $bytes);
If you start with the binary representation of the bits, use the following first:
my $bytes = packed('B*', $bits);
(This assumes the number of bits is divisible by 8. Left-pad with zeroes if it isn't, and don't forget to remove the extra entries this creates in #decode.)
Is this any faster?
#!/usr/bin/env perl
use warnings;
use strict;
my %bin2dec = (
'0' => 0,
'1' => 1,
'00' => 0,
'01' => 1,
'10' => 2,
'11' => 3
);
#warn "$_ => $bin2dec{$_}\n" for sort keys %bin2dec;
my #results;
while (<>)
{
foreach my $bitstring (/([01]+)/g)
{
my #result;
#warn "bitstring is $bitstring\n";
for ( my $i = 0 ; $i < length($bitstring) ; $i += 2 )
{
#warn "value is ", substr( $bitstring, $i, 2 ), "\n";
push( #result, $bin2dec{ substr( $bitstring, $i, 2 ) } );
}
push( #results, \#result );
}
}
foreach my $result (#results)
{
print join( ' ', #$result ), "\n";
}
saved to file b2dec. Example output:
$ echo 10010101010010010101001111001011010101w00101010 | b2dec
2 1 1 1 1 0 2 1 1 1 0 3 3 0 2 3 1 1 1
0 2 2 2
$ b2dec b2dec
0
0
1
1
0
0
1
1
2
3
1
0

Resources