How do I generate MD5 of a string in AHK Windows 10? - md5

I tried the code from https://github.com/acmeism/RosettaCodeData/blob/master/Task/MD5/AutoHotkey/md5-1.ahk, which did work with windows 7:
data := "abc"
MsgBox % MD5(data,StrLen(data)) ; 900150983cd24fb0d6963f7d28e17f72
MD5( ByRef V, L=0 ) {
VarSetCapacity( MD5_CTX,104,0 ), DllCall( "advapi32\MD5Init", Str,MD5_CTX )
DllCall( "advapi32\MD5Update", Str,MD5_CTX, Str,V, UInt,L ? L : VarSetCapacity(V) )
DllCall( "advapi32\MD5Final", Str,MD5_CTX )
Loop % StrLen( Hex:="123456789ABCDEF0" )
N := NumGet( MD5_CTX,87+A_Index,"Char"), MD5 .= SubStr(Hex,N>>4,1) . SubStr(Hex,N&15,1)
Return MD5
}
However, some dll calls must be non-functional now, since it does not return the right values with windows 10. For example, the given code snippet returns 70350F6027BCE3713F6B76473084309B instead of 900150983cd24fb0d6963f7d28e17f72. I also tried running it with administrator rights. Not sure what is the reason behind this. I haven't been able to access the MD5-functions in the advapi32 dll directly, for some reason.
What should I do to get a correct MD5 hash?

Not sure if it'll work on windows 10 but there is a Native version posted on Rosetta code:
http://rosettacode.org/wiki/MD5#Native_implementation
Source: AutoHotkey forum by Laszlo
; GLOBAL CONSTANTS r[64], k[64]
r = 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22
, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20
, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23
, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
StringSplit r, r, `,
r0 := 7
Loop 64
i := A_Index-1, k%i% := floor(abs(sin(A_Index)) * 2**32)
; TEST CASES
MsgBox % MD5(x:="", 0) ; d41d8cd98f00b204e9800998ecf8427e
MsgBox % MD5(x:="a", StrLen(x)) ; 0cc175b9c0f1b6a831c399e269772661
MsgBox % MD5(x:="abc", StrLen(x)) ; 900150983cd24fb0d6963f7d28e17f72
MsgBox % MD5(x:="message digest", StrLen(x)) ; f96b697d7cb7938d525a2f31aaf161d0
MsgBox % MD5(x:="abcdefghijklmnopqrstuvwxyz", StrLen(x))
; c3fcd3d76192e4007dfb496cca67e13b
MsgBox % MD5(x:="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", StrLen(x))
; d174ab98d277d9f5a5611c2c9f419d9f
MsgBox % MD5(x:="12345678901234567890123456789012345678901234567890123456789012345678901234567890", StrLen(x))
; 57edf4a22be3c955ac49da2e2107b67a
MsgBox % MD5(x:="The quick brown fox jumps over the lazy dog", StrLen(x))
; 9e107d9d372bb6826bd81d3542a419d6
MsgBox % MD5(x:="The quick brown fox jumps over the lazy cog", StrLen(x))
; 1055d3e698d289f2af8663725127bd4b
MD5(ByRef Buf, L) { ; Binary buffer, Length in bytes
Static P, Q, N, i, a,b,c,d, t, h0,h1,h2,h3, y = 0xFFFFFFFF
h0 := 0x67452301, h1 := 0xEFCDAB89, h2 := 0x98BADCFE, h3 := 0x10325476
N := ceil((L+9)/64)*64 ; padded length (100..separator, 8B length)
VarSetCapacity(Q,N,0) ; room for padded data
P := &Q ; pointer
DllCall("RtlMoveMemory", UInt,P, UInt,&Buf, UInt,L) ; copy data
DllCall("RtlFillMemory", UInt,P+L, UInt,1, UInt,0x80) ; pad separator
DllCall("ntdll.dll\RtlFillMemoryUlong",UInt,P+N-8,UInt,4,UInt,8*L) ; at end: length in bits < 512 MB
Loop % N//64 {
Loop 16
i := A_Index-1, w%i% := *P | *(P+1)<<8 | *(P+2)<<16 | *(P+3)<<24, P += 4
a := h0, b := h1, c := h2, d := h3
Loop 64 {
i := A_Index-1
If i < 16
f := (b & c) | (~b & d), g := i
Else If i < 32
f := (d & b) | (~d & c), g := 5*i+1 & 15
Else If i < 48
f := b ^ c ^ d, g := 3*i+5 & 15
Else
f := c ^ (b | ~d), g := 7*i & 15
t := d, d := c, c := b
b += rotate(a + f + k%i% + w%g%, r%i%) ; reduced to 32 bits later
a := t
}
h0 := h0+a & y, h1 := h1+b & y, h2 := h2+c & y, h3 := h3+d & y
}
Return hex(h0) . hex(h1) . hex(h2) . hex(h3)
}
rotate(a,b) { ; 32-bit rotate a to left by b bits, bit32..63 garbage
Return a << b | (a & 0xFFFFFFFF) >> (32-b)
}
hex(x) { ; 32-bit little endian hex digits
SetFormat Integer, HEX
x += 0x100000000, x := SubStr(x,-1) . SubStr(x,8,2) . SubStr(x,6,2) . SubStr(x,4,2)
SetFormat Integer, DECIMAL
Return x
}

These hash functions from jNizM seem to work: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=21
For MD5:
md5(string) ; // by SKAN | rewritten by jNizM
{
hModule := DllCall("LoadLibrary", "Str", "advapi32.dll", "Ptr")
, VarSetCapacity(MD5_CTX, 104, 0), DllCall("advapi32\MD5Init", "Ptr", &MD5_CTX)
, DllCall("advapi32\MD5Update", "Ptr", &MD5_CTX, "AStr", string, "UInt", StrLen(string))
, DllCall("advapi32\MD5Final", "Ptr", &MD5_CTX)
loop, 16
o .= Format("{:02" (case ? "X" : "x") "}", NumGet(MD5_CTX, 87 + A_Index, "UChar"))
DllCall("FreeLibrary", "Ptr", hModule)
StringLower, o,o
return o
}

Related

How to make series with a given array?

I am a VB.Net user. I would like to make an array as per below
Dim QRList() As Integer = {1, 2, 3, 4, 9, 12, 13, 14, 15, 16, 41, 42, 44, 48, 49, 50}
into a series as per below
1 - 4,
9 - 9,
12 - 16,
41 - 42,
44 - 44,
48 - 50,
I have tried the code below. But it doesn't work.
Dim QRList() As Integer = {1, 2, 3, 4, 9, 12, 13, 14, 15, 16, 41, 42, 44, 48, 49, 50}
Dim QRCount As Integer = QRList.Length
Dim startIndex, startN, endN As Integer
For i As Integer = 0 to QRCount - 1
startindex = 0
i = startindex
startN = QRList(i)
Do
If startindex = QRCount - 1 Then
endN = QRList(i)
ElseIf startindex < QRCount - 1 Then
If QRList(i + 1) - QRList(i) + 1 = 1 Then
endN = QRList(i + 1)
ElseIf QRList(i + 1) - QRList(i) + 1 > 1 Then
endN = QRList(i)
Exit For
End If
End If
startindex = i + 1
Console.Writeline(CStr(startN) & " - " & CStr(endN) & vbNewLine)
Loop While startindex < QRCount
Next
Hope anyone can help on this issue, Thanks.
Austin HO
This is a perfect candidate for the Yield statement to return an IEnumerable(Of String). You can pass that resulting IEnumerable(Of String) to String.Join() to obtain the final result.
Here's a quick example:
Sub Main()
Dim QRList() As Integer = {1, 2, 3, 4, 9, 12, 13, 14, 15, 16, 41, 42, 44, 48, 49, 50}
Dim series As String = String.Join("," & vbCrLf, GetSeries(QRList))
Console.WriteLine("Original: " & String.Join(", ", QRList))
Console.WriteLine("Series:")
Console.WriteLine(series)
Console.Write("Press Enter to quit...")
Console.ReadLine()
End Sub
Public Iterator Function GetSeries(ByVal values() As Integer) As IEnumerable(Of String)
Dim startNum, endNum As Integer?
For Each value As Integer In values
If Not startNum.HasValue Then
startNum = value
endNum = value
ElseIf value = (endNum + 1) Then
endNum = value
Else
Yield startNum & " - " & endNum
startNum = value
endNum = value
End If
Next
Yield startNum & " - " & endNum
End Function
Producing the following output:
Original: 1, 2, 3, 4, 9, 12, 13, 14, 15, 16, 41, 42, 44, 48, 49, 50
Series:
1 - 4,
9 - 9,
12 - 16,
41 - 42,
44 - 44,
48 - 50
Press Enter to quit...
Just to make it extra clear what is happening, you can convert the iterator to an array like this:
Dim arrSeries() As String = GetSeries(QRList).ToArray
For i As Integer = 0 To arrSeries.Length - 1
Console.WriteLine(i & ": " & arrSeries(i))
Next
Producing:
0: 1 - 4
1: 9 - 9
2: 12 - 16
3: 41 - 42
4: 44 - 44
5: 48 - 50
And, finally, if you need to work with the actual Integer start and stop values as a set, then simply convert the iterator function to return IEnumerable(Of Tuple(Of Integer, Integer)) instead, and use this Yield statement in the function in both places:
Yield New Tuple(Of Integer, Integer)(startNum, endNum)
Your loop fails at the first comparison: If QRList(i + 1) - QRList(i) + 1 = 1.
Since the condition is not met, the execution continues to the endN = QRList(i) assignment and exits the for loop entirely.
You can simplify this process a bit.
Since you need to generate sequences of contiguous numbers, you just need to determine the starting values - values in the original series that have a distance > 1 - and a variable to store the value of the previous iteration, used to perform the comparison.
Here, I'm using a List of named tuples (List(Of (StartValue As Integer, EndValue As Integer)) to store the values in the series.
You can use a List(Of String), or another type of collection, if that's preferable or named Tuples are not available
Dim QRList As Integer() = { 9, 12, 13, 14, 15, 16, 41, 42, 44, 48, 49, 50, 1, 2, 3, 4}
' Sort the array in case it's not already sorted
Array.Sort(QRList)
Dim maxDistance As Integer = 1
Dim seriesCount As Integer = -1
' Assign starting values that are less than ([Min Value] - [Max Distance])
Dim startValue As Integer = QRList(0) - (maxDistance + 1)
Dim previousValue As Integer = startValue
Dim series As New List(Of (StartValue As Integer, EndValue As Integer))()
For Each value As Integer In QRList
' The distance is less than or equal to the maximum: update the current item
If (value - maxDistance) <= previousValue Then
series(seriesCount) = (startValue, value)
Else
' The distance is > maxDistance: add a new starting item
startValue = value
series.Add((value, value))
seriesCount += 1
End If
previousValue = value
Next
To print the elements in the series:
For Each t In series
Console.WriteLine($"{t.StartValue} - {t.EndValue}")
Next
With maxDistance = 1, the series are:
1 - 4
9 - 9
12 - 16
41 - 42
44 - 44
48 - 50
With maxDistance = 4, the series are:
1 - 4
9 - 16
41 - 50

Multidimensional Array - set to table data from array

I have problem with Multidimensional Array. I created calculate between two types of data from one table.
Example data from table BT_MATRYCA.
And I division data from TYP: VAL_A since COL1 to COL17 by value from SUMA_RAZEM from row with TYP: VAL_B.
Command "put d_st[i,j] =;" puts good value but I need create table with this calculate (Multidimensional, with X and Y). How I can do?
data BT_MATRYCA;
infile DATALINES dsd missover;
input NAME $ TYP $ COL1 COL2 COL3 COL4 COL5 COL6 COL7 COL8 COL9 COL10 COL11 COL12 COL13 COL14 COL15 COL16 COL17 SUMA_RAZEM;
CARDS;
A1, VAL_A, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 500
A1, VAL_B, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 600
B1, VAL_A, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 12, 13, 14, 15, 16, 16, 20, 550
B1, VAL_B, 1, 20, 3, 20, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 800
C1, VAL_A, 20, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 12, 13, 14, 15, 16, 17, 900
C1, VAL_B, 1, 2, 3, 20, 5, 6, 7, 8, 02, 10, 11, 12, 30, 14, 15, 16, 17, 780
;run;
data t3;
array m[6,18] _temporary_;
array n[6,18] _temporary_;
array d_st[6,18] _temporary_;
call missing(of d_st[*]);
if _n_ = 1 then do;
do i = 1 by 1 until(z1);
set BT_MATRYCA (where=(TYP = 'VAL_A')) end = z1;
array c[18] COL1--SUMA_RAZEM;
do j = 1 to 18;
m[i, j] = c[j];
end;
end;
do i = 1 by 1 until(z2);
set BT_MATRYCA (where=(TYP = 'VAL_B')) end = z2;
array v[18] COL1--SUMA_RAZEM;
do j = 1 to 18;
n[i,j] = v[j];
end;
end;
end;
do i = 1 to 6;
do j = 1 to 18;
IF m[i,18] ne 0 then
d_st[i,j] = coalesce((n[i,j] / m[i,18]),0);
ELSE
d_st[i,j] = 0;
end;
end;
do i = 1 to 6;
do j = 1 to 18;
put d_st[i,j] =;
end;
end;
stop;
run;
`
It isn't particularly clear what you're asking, but it sounds as though you want something like this:
data t3 wide(keep = x1-x6) long(keep = x y z);
array m[6,18] _temporary_;
array n[6,18] _temporary_;
array d_st[6,18] _temporary_;
array _x[6] x1-x6;
put d_st[1,1]=;
if _n_ = 1 then do;
do i = 1 by 1 until(z1);
set BT_MATRYCA (where=(TYP = 'VAL_A')) end = z1;
array c[18] COL1--SUMA_RAZEM;
do j = 1 to 18;
m[i, j] = c[j];
end;
end;
do i = 1 by 1 until(z2);
set BT_MATRYCA (where=(TYP = 'VAL_B')) end = z2;
array v[18] COL1--SUMA_RAZEM;
do j = 1 to 18;
n[i,j] = v[j];
end;
end;
end;
do i = 1 to 6;
do j = 1 to 18;
IF m[i,18] ne 0 then
d_st[i,j] = coalesce((n[i,j] / m[i,18]),0);
ELSE
d_st[i,j] = 0;
end;
end;
/* Note switching of inner and outer loops*/
do j = 1 to 18;
do i = 1 to 6;
_x[i] = d_st[i,j];
x = i;
y = j;
z = d_st[i,j];
output long;
end;
output wide;
end;
stop;
run;

What is the most efficient way to get the intersection and exclusions from two arrays/slices?

Given two arrays or slices for eg:
a := []int{1, 2, 3, 4, 5}
b := []int{3, 4, 5, 6, 7, 8, 9}
The slices may not be sorted and order doesn't matter.
What is the most efficient way to compute values such that you end up with the common elements of both slices, and the remainder of elements present in one but not the other i.e for the two arrays given above the return values would be:
common := []int{3, 4, 5}
inAButNotB := []int{1, 2}
inBButNotA := []int{6, 7, 8, 9}
Its easy to compute the intersection converting one slice into a map and then iterating over the one to see if values exist. Is there a way to compute the other two values within the same loop?
O(len(a) + len(b)) is efficient. For example,
package main
import (
"fmt"
)
func main() {
a := []int{1, 2, 3, 4, 5}
b := []int{3, 4, 5, 6, 7, 8, 9}
fmt.Println(a)
fmt.Println(b)
m := make(map[int]uint8)
for _, k := range a {
m[k] |= (1 << 0)
}
for _, k := range b {
m[k] |= (1 << 1)
}
var inAAndB, inAButNotB, inBButNotA []int
for k, v := range m {
a := v&(1<<0) != 0
b := v&(1<<1) != 0
switch {
case a && b:
inAAndB = append(inAAndB, k)
case a && !b:
inAButNotB = append(inAButNotB, k)
case !a && b:
inBButNotA = append(inBButNotA, k)
}
}
fmt.Println(inAAndB)
fmt.Println(inAButNotB)
fmt.Println(inBButNotA)
}
Playground: https://play.golang.org/p/RvGaC9Wfjiv
Output:
[1 2 3 4 5]
[3 4 5 6 7 8 9]
[3 4 5]
[1 2]
[8 6 7 9]
The Go Programming Language Specification
& bitwise AND integers
| bitwise OR integers
^ bitwise XOR integers
&^ bit clear (AND NOT) integers
<< left shift integer << unsigned integer
>> right shift integer >> unsigned integer
We have 8 bits for uint8. Bit 0 (1 << 0, 1 shift left 0) is a and bit 1 (1 << 1; 1 shift left 1) is b. For uint8 bits, 00000001 is a, 00000010 is b, 00000011 is a and b, and 00000000 is nether a nor b. The | operator sets a bit, the & operator reads a bit.
The Go Programming Language Specification
Map types
A map is an unordered group of elements of one type, called the
element type, indexed by a set of unique keys of another type, called
the key type.
The comparison operators == and != must be fully defined for operands
of the key type; thus the key type must not be a function, map, or
slice. If the key type is an interface type, these comparison
operators must be defined for the dynamic key values; failure will
cause a run-time panic.
The algorithm works for any slice type whose elements can be a map key. The comparison operators == and != must be fully defined for operands of the key type.

Binary search Circulary rotated array

I am trying to execute a Binary search to find an element in a circularly sorted array. I get a type error that I don't seem to understand. Any suggestions/modifications will be appreciated.
here is my code:
def Binarysearch(a, low, high, x):
if low > high:
return -1
else:
mid = (low + high)/2
if x == a[mid]:
return mid
elif a[mid] <= a[high]:
if x > a[mid] and x <= a[high]:
return Binarysearch(a, mid+1, high, x)
elif a[mid] >= a[low]:
if x >= a[low] and x < a[mid]:
return Binarysearch(a, low, mid-1, x)
elem_list = [6, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5]
x = int(raw_input('enter search elemet'))
lenlist = len(elem_list)
result = Binarysearch(elem_list, 0, lenlist-1, x)
if result == -1:
print "Not found"
else:
print "Found it", elem_list[result]
I get error:
Line32: TypeError: list indices must be integers, not NoneType
Unless this is a learning exercise you may want to use the bisect module instead. e.g.
from bisect import bisect_left
def search(l, x): # search x in l
if len(l) > 0:
p = min((e,i) for i,e in enumerate(l))[1] # min element index
p1 = bisect_left(l, x, 0, p) # search left
if p1 < p and l[p1]==x:
return p1
p2 = bisect_left(l, x, p) # search right
if p2 < len(l) and l[p2]==x:
return p2
interactive demonstration:
>>> elem_list = [6, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5]
>>> for e in elem_list:
... assert e == elem_list[search(elem_list, e)]
...
>>> for e in [-1, 7, 8, 999]:
... assert None == search(elem_list, e)
...
>>> elem_list.sort()
>>> elem_list
[1, 2, 3, 4, 5, 6, 11, 12, 13, 14, 15, 16]
>>> for e in elem_list:
... assert e == elem_list[search(elem_list, e)]
...
>>> for e in [-1, 7, 8, 999]:
... assert None == search(elem_list, e)
...
>>> assert None == search([], 123)
See also
Binary search (bisection) in Python
def rotated_binary_search(A, N, key):
L = 0
R = N - 1
while (L <= R):
M = L + ((R - L) / 2)
if (A[M] == key): return M
# the bottom half is sorted
if (A[L] <= A[M]):
if (A[L] <= key and key < A[M]):
R = M - 1
else:
L = M + 1
# the upper half is sorted
else:
if (A[M] < key and key <= A[R]):
L = M + 1
else:
R = M - 1
return -1
A = [6, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5]
N = len(A)
result = rotated_binary_search(A, N, 13)
print "Original List", A
if result == -1:
print "Not found"
else:
print "Found", A[result], "at position", result`enter code here`
Result:
Original List [6, 11, 12, 13, 14, 15, 16, 1, 2, 3, 4, 5]
Found 13 at position 3

How can I convert 1D array into 2D matrix on MATLAB?

I want to make heatmap with 1D array(s), this is my plan;
Let assume 4 points of center and each has array,
[center #1, L U] = {0, 1, 2, 5, 10, 7, 4, 2, 1, 0} *L R U D = Left, Right, Up, Down
[center #2, R U] = {0, 1, 1, 4, 12, 7, 5, 3, 2, 1}
[center #3, L D] = {0, 1, 3, 4, 11, 7, 4, 2, 1, 0}
[center #4, R D] = {0, 1, 3, 6, 11, 6, 5, 3, 1, 1}
And when 5th index of heatmap, ([#1]=10, [#2]=12, [#3]=11, [#4]=11) heatmap needs to be like this image.
Heatmap image
Also can predict heatmap is all blue when 1st index ([#1]=0, [#2]=0, [#3]=0, [#4]=0) and only right side has color that almost blue when last index. ([#1]=0, [#2]=1, [#3]=0, [#4]=1)
How can I get 2D matrix from 1D arrays on Matlab? Decreasing values from center can be linear or whatever.
Based on your example you wish to produce always 4 n * n matrices, where the center point of each matrix gets the value in your arrays and all its 4-neighbors get a decreasing value until zero. Did I get it right?
Does this create one of the four matrices you wished to create? If so, just modify the parameters and make four matrices and draw them together
% your matrix size
size = 15
center = (size + 1) / 2
center_value = 5
mat_a = zeros(size,size);
mat_a(center,center) = center_value;
%loop all values until zero
for ii=1:center_value -1
current_value = center_value - ii;
update_mat = mat_a;
% loop over matrix, check if 4-neighbors non-zero
for x =1:size
for y =1:size
if ( mat_a(y,x) == 0 )
has_non_zero_neighbor = false;
% case 1
if ( x < size)
if (mat_a(y,x+1) > 0)
has_non_zero_neighbor = true;
endif
endif
% case 2
if ( y < size)
if (mat_a(y+1,x) > 0)
has_non_zero_neighbor = true;
endif
endif
%case 3
if ( x > 1)
if (mat_a(y,x-1) > 0)
has_non_zero_neighbor = true;
endif
endif
% case 4
if ( y > 1)
if (mat_a(y-1,x) > 0)
has_non_zero_neighbor = true;
endif
endif
%if non-zeros, update matrix item value to current value
if (has_non_zero_neighbor == true)
update_mat(y,x) = current_value;
endif
endif
end
end
mat_a = update_mat;
end
figure(1)
imshow(mat_a./center_value)

Resources