I have access to some VC++ source code for which I am trying to convert to VB.NET. I previously asked a question regarding bit shifting, and although the answers given made sense and seemed rather simple to convert over to VB.NET, I am having difficulty getting things to work out. Here is some VC++ code that I am needing to convert to VB.NET:
#define bitShift(_val) \
((u64)(((((u64)_val) & 0xff00000000000000ull) >> 56) | \
((((u64)_val) & 0x00ff000000000000ull) >> 40) | \
((((u64)_val) & 0x0000ff0000000000ull) >> 24) | \
((((u64)_val) & 0x000000ff00000000ull) >> 8 ) | \
((((u64)_val) & 0x00000000ff000000ull) << 8 ) | \
((((u64)_val) & 0x0000000000ff0000ull) << 24) | \
((((u64)_val) & 0x000000000000ff00ull) << 40) | \
((((u64)_val) & 0x00000000000000ffull) << 56)))
Now, the returned value will be used as the counter for AES decryption in CTR Mode. The following VC++ code is used to calculate the counter:
u8 counter[16];
*(u64 *)(counter + 0) = bitShift(i);
*(u64 *)(counter + 8) = 0;
This is where I am currently at with the VB.NET code:
Public Function SwapBits(ByVal value As Int64) As Int64
Dim uvalue As UInt64 = CULng(value)
Dim swapped As UInt64 = ((&HFF00000000000000UL) And (uvalue >> 56) Or _
(&HFF000000000000L) And (uvalue >> 40) Or _
(&HFF0000000000L) And (uvalue >> 24) Or _
(&HFF00000000L) And (uvalue >> 8) Or _
(&HFF000000UI) And (uvalue << 8) Or _
(&HFF0000) And (uvalue << 24) Or _
(&HFF00) And (uvalue << 40) Or _
(&HFF) And (uvalue << 56))
Return CLng(swapped)
End Function
Here is the code used to create the counter:
Dim blocks As Integer = file_size / 16
For i As Integer = 0 To blocks - 1
Dim buffer As Byte() = New Byte(15) {}
Array.Copy(BitConverter.GetBytes(SwapBits(CULng(i))), 0, buffer, 0, 8)
'AES decryption takes place after this...
The counter is 16 bytes, but only the first 8 bytes are encrypted using AES 128 bit EBC and then XOR'd with the current encrypted block of data which is also 16 bytes (AES CTR Mode). I can get the code to run without any errors, but the output of decrypted data is incorrect which leads me to believe I am not calculating the counter which is being used for encryption correctly.
Once again, any help is obviously appreciated, and thanks in advance!
EDIT: Current SwapBits function... still not right though
Public Function SwapBits(ByVal uvalue As UInt64) As UInt64
Dim swapped As UInt64 = ((((uvalue) And &HFF00000000000000) >> 56) Or _
(((uvalue) And &HFF000000000000) >> 40) Or _
(((uvalue) And &HFF0000000000) >> 24) Or _
(((uvalue) And &HFF00000000) >> 8) Or _
(((uvalue) And &HFF000000) << 8) Or _
(((uvalue) And &HFF0000) << 24) Or _
(((uvalue) And &HFF00) << 40) Or _
(((uvalue) And &HFF) << 56))
Return swapped
End Function
This actually causes an "Arithmetic operation resulted in an overflow." error when uvalue reaches a value of 128. When the value of 1 is passed to SwapBits, my return value = 72057594037927936. My interpretation of the VC++ code is that my counter should simply be a 16 byte array incrementing by 1 each time. For example, if
uvalue = 1
then my counter needs to be
0000000100000000
if
uvalue = 25
then my counter needs to be
0000002500000000
etc, etc... Or I am misinterpreting something somewhere?
Not sure what you're expecting from the C++ code. But when I use this:
#include <iostream>
using namespace std;
#define bitShift(_val) \
((unsigned __int64)(((((unsigned __int64)_val) & 0xff00000000000000ull) >> 56) | \
((((unsigned __int64)_val) & 0x00ff000000000000ull) >> 40) | \
((((unsigned __int64)_val) & 0x0000ff0000000000ull) >> 24) | \
((((unsigned __int64)_val) & 0x000000ff00000000ull) >> 8 ) | \
((((unsigned __int64)_val) & 0x00000000ff000000ull) << 8 ) | \
((((unsigned __int64)_val) & 0x0000000000ff0000ull) << 24) | \
((((unsigned __int64)_val) & 0x000000000000ff00ull) << 40) | \
((((unsigned __int64)_val) & 0x00000000000000ffull) << 56)))
int main()
{
unsigned __int64 test = bitShift(25);
return 0;
}
I get the exact same return value(1801439850948198400 || &H1900000000000000) as this:
Dim result As ULong = SwapBits(25)
Public Function SwapBits(ByVal uvalue As UInt64) As UInt64
Dim swapped As UInt64 = ((((uvalue) And &HFF00000000000000UL) >> 56) Or _
(((uvalue) And &HFF000000000000UL) >> 40) Or _
(((uvalue) And &HFF0000000000UL) >> 24) Or _
(((uvalue) And &HFF00000000UL) >> 8) Or _
(((uvalue) And &HFF000000UL) << 8) Or _
(((uvalue) And &HFF0000UL) << 24) Or _
(((uvalue) And &HFF00UL) << 40) Or _
(((uvalue) And &HFFUL) << 56))
Return swapped
End Function
I don't have much experience in C++, care to share what this is doing:
u8 counter[16];
*(u64 *)(counter + 0) = bitShift(i);
*(u64 *)(counter + 8) = 0;
basically that section of code increments the first 8 bytes of counter by 1 each iteration 0f i, starting with the right most byte and expanding left for each carryover. For instance, if the counter reaches 999 counter[7] will hold 231(&HE7) and counter[6] 3(&H3) which when you look at the whole array gives, &H000000000003E7 which equals 999 decimal.
Something tells me conversion is better done using the GetBytes and ToUInt64() methods, a for loop and a temporary variable. It would be much easier to read and probably fast enough for most purposes.
Related
I am trying to get this snippet to vb but keep getting errors in the ide
var header = new byte[8];
int index = 0;
var magic_signature = ((uint)header[index++] << 0) | ((uint)header[index++] << 8) | ((uint)header[index++] << 16) | ((uint)header[index++] << 24);
I tried an online coverter and got this (which produces errors)
Dim magic_signature = (CUInt(header(Math.Max(Threading.Interlocked.Increment(index), index - 1))) << 0) Or (CUInt(header(Math.Max(Threading.Interlocked.Increment(index), index - 1))) << 8) Or (CUInt(header(Math.Max(Threading.Interlocked.Increment(index), index - 1))) << 16) Or (CUInt(header(Math.Max(Threading.Interlocked.Increment(index), index - 1))) << 24)
The header variable is filled after declaration.
Could someone help me convert the above to vb.net?
EDIT:
Populating header via reading a stream
Dim header = New Byte(8) {}
If stream.Read(header, 0, 8) < 8 Then
Throw New ApplicationException("Incomplete data.")
End If
As Mike_OBrien has pointed out, VB doesn't have a built-in ++ - but we can fake one easily enough:
Function PostIncr(ByRef x As Integer) As Integer
' PostIncr(i) works like i++
Dim x0 As Integer = x : x += 1 : Return x0
End Function
After that, conversion is straightforward:
Dim header(7) As Byte
' Make believe this is a stream.Read
Array.Copy({CByte(1), CByte(2), CByte(3), CByte(4)},
header, 4)
Dim index As Integer = 0
Dim magic_signature = CUInt(header(PostIncr(index))) << 0 Or
CUInt(header(PostIncr(index))) << 8 Or
CUInt(header(PostIncr(index))) << 16 Or
CUInt(header(PostIncr(index))) << 24
And for fun:
Function PreIncr(ByRef x As Integer) As Integer
' PreIncr(i) works like ++i
x += 1 : Return x
End Function
I believe David Wilson is on the right path but as rskar pointed out the Index + 1 portion does not produce the same results as index++ would in c#. The easiest way to get the behavior from c# would be to break the single command into multiple commands and store the results in temp variables, incrementing Index between each step and then evaluating the temp variables at the end. This would result in a lot more code however.
Ex:
Dim temp1 = (CUInt(header(Index)) << 0)
Index += 1
Dim temp2 = (CUInt(header(Index)) << 8)
Index += 1
Dim temp3 = (CUInt(header(Index)) << 16)
Index += 1
Dim magic_signature As UInteger = temp1 Or temp2 Or temp3 Or (CUInt(header(Index)) << 24)
Unfortunately to my knowledge there isn't anything in vb.net that behaves the same as the ++ operator in c#.
I'm trying to convert a four digit number into an IP Address. For example:
0001 ---> *.192.1.01
0011 ---> *.192.11.01
0111 ---> *.192.111.01
1111 ---> *.196.87.01
3458 ---> *.205.130.01
I believe the subnet mask is 255.255.192.0.
I would greatly appreciate any suggestions on the best way to do this in vb.net.
Other info:
This is for a simple pinger program where the user inputs a four digit number (the ID of the physical site that they wish to ping.) The IP Addressing scheme is simple, the 2nd & 3rd octet are used as the site number, and the fourth octet is used as the device at the site. I didn't design this scheme, hence why I'm unsure on how to get vb.net to understand it.
What I've Tried:
I thought about doing it the following way, which is extremely crude. However this would only work up to *.192.255.01 as I don't know how to split the number between the two octets once it goes over 255 in octet 3.
Private Sub btnStartPing(sender As Object, e As EventArgs) Handles btnStartPing.Click
Dim Octet1 As Integer = *
Dim Octet2 As Integer = 192
Dim Octet3 As Integer = txtSiteID.text
Dim Octet4 As Integer = 01
Dim CompleteIP As String = ""
CompletIP = Octet1 & "." & Octet2 & "." & Octet3 & "." & Octet4
'PING CompleteIP
end sub
Solution:
Dim var1 As Integer = Fix(192 + (NumericUpDown1.Value / 256))
Dim var2 As Integer = Fix((NumericUpDown1.Value Mod 256))
MsgBox("Your IP address is: " & "10." & var1 & "." & var2 & "." & "200")
End Sub
You'll need to split the number in two. Get the first half of the bits and add them to 192 and the second half of the bits are directly used.
Dim number As Integer
number = 1
Console.WriteLine("*.{0}.{1}.01", 192 + ((number And &HFF00) >> 8), number And &HFF) ' *.192.1.01
number = 11
Console.WriteLine("*.{0}.{1}.01", 192 + ((number And &HFF00) >> 8), number And &HFF) ' *.192.11.01
number = 111
Console.WriteLine("*.{0}.{1}.01", 192 + ((number And &HFF00) >> 8), number And &HFF) ' *.192.111.01
number = 1111
Console.WriteLine("*.{0}.{1}.01", 192 + ((number And &HFF00) >> 8), number And &HFF) ' *.196.87.01
number = 3458
Console.WriteLine("*.{0}.{1}.01", 192 + ((number And &HFF00) >> 8), number And &HFF) ' *.205.130.01
Take the number and split it in two
3458 = 0x0D82
0x0D
0x82
Then add 192 to the first part
0x0D + 192 = 205
0x82 = 130
This should make it
Public Function StartPing(txtSiteId As String) As String
Dim SiteId As Integer = Integer.Parse(txtSiteId)
'backslash performs integer division (no fractionary part)
'will throw an error when SiteId results in values greater than 255
'type Byte allows only values from 0 to 255
Dim Octet2 As Byte = 192 + (SiteId \ 256)
'Mod gets rest of division
Dim Octet3 As Byte = SiteId Mod 256
Return String.Format("*.{0}.{1}.01", Octet2, Octet3)
End Function
I am attempting to get the following code working for a Fibonacci shift register to generate pseudo-random numbers. Can't seem to get it working, so is(are) there any obvious issues(?)
Shared Function Main() As Integer
Dim start_state As UShort = &HACE1UI ' Any nonzero start state will work.
Dim lfsr As UShort = start_state
Dim bit As UInteger
Dim period As UInteger = 0
Do While lfsr <> start_state
' taps: 16 14 13 11; feedback polynomial: x^16 + x^14 + x^13 + x^11 + 1
bit = ((lfsr >> 0) Xor (lfsr >> 2) Xor (lfsr >> 3) Xor (lfsr >> 5)) And 1
lfsr = (lfsr >> 1) Or (bit << 15)
period += 1
Loop
Return 0
End Function
Last, does "period" need to be divided by a large integer to get U(0,1)'s?
Below is the original C++ code:
# include <stdint.h>
int main(void)
{
uint16_t start_state = 0xACE1u; /* Any nonzero start state will work. */
uint16_t lfsr = start_state;
uint16_t bit; /* Must be 16bit to allow bit<<15 later in the code */
unsigned period = 0;
do
{
/* taps: 16 14 13 11; feedback polynomial: x^16 + x^14 + x^13 + x^11 + 1 */
bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1;
lfsr = (lfsr >> 1) | (bit << 15);
++period;
} while (lfsr != start_state);
return 0;
}
As in #dummy's comment,
Do While lfsr <> start_state
...
Loop
doesn't run because lfsr = start_state at the beginning.
The code equivalent to C++
do {
...
} while (lfsr != start_state);
in VB.NET is
Do
...
Loop While lfsr <> start_state
I made some attempts to implement an efficient of rc4 cipher algorithm in cuda. I used shared memory to store the internal permutation state, taking care of the banked memory layout to time penalty with parallel thread accesses in the warp. I also tried to minimize the number of accesses exploiting the fact that read/write accesses with the 'i' index are contiguous and can be packed in 32-bits words. Last, I made use of constant memory to initialize the permutation state.
Despite these 'clever' tricks, i can expect to achieve only roughly 50% of throughput of the best reported implementations (see guapdf cracker for example), even taking into consideration that unblocked communication between host and gpu could be used to partially cover the computation. I can't figure why and I am looking for new improvement ideas or comments on bad assumptions i could have made.
Here is a toy implementation of my KSA (key setting) kernel with a key reduced to 4 bytes.
__constant__ unsigned int c_init[256*32/4];
__global__ void rc4Block(unsigned int *d_out, unsigned int *d_in)
{
__shared__ unsigned int s_data[256*32/4];
int inOffset = blockDim.x * blockIdx.x;
int in = inOffset + threadIdx.x;
unsigned int key, u;
// initialization
key = d_in[in];
for(int i=0; i<(256/4); i++) { // read from constant memory
s_data[i*32+threadIdx.x] = c_init[i*32+threadIdx.x];
}
// key mixing
unsigned char j = 0;
unsigned char k0 = key & 0xFF;
unsigned char k1 = (key >> 8) & 0xFF;
unsigned char k2 = (key >> 8) & 0xFF;
unsigned char k3 = (key >> 8) & 0xFF;
for(int i=0; i<256; i+=4) { // unrolled
unsigned int u, sj, v;
unsigned int si = s_data[(i/4)*32+threadIdx.x];
unsigned int shiftj;
u = si & 0xff;
j = (j + k0 + u) & 0xFF;
sj = s_data[(j/4)*32+threadIdx.x];
shiftj = 8*(j%4);
v = (sj >> shiftj) & 0xff;
si = (si & 0xffffff00) | v;
sj = (sj & ~(0xFFu << (8*(j%4)))) | (u << shiftj);
s_data[(j/4)*32+threadIdx.x] = sj;
u = (si >> 8) & 0xff;
j = (j + k1 + u) & 0xFF;
sj = s_data[(j/4)*32+threadIdx.x];
shiftj = 8*(j%4);
v = (sj >> shiftj) & 0xff;
si = (si & 0xffff00ff) | (v<<8);
sj = (sj & ~(0xFFu << (8*(j%4)))) | (u << shiftj);
s_data[(j/4)*32+threadIdx.x] = sj;
u = (si >> 16) & 0xff;
j = (j + k2 +u) & 0xFF;
sj = s_data[(j/4)*32+threadIdx.x];
shiftj = 8*(j%4);
v = (sj >> shiftj) & 0xff;
si = (si & 0xff00ffff) | (v<<16);
sj = (sj & ~(0xFFu << (8*(j%4)))) | (u << shiftj);
s_data[(j/4)*32+threadIdx.x] = sj;
u = (si >> 24) & 0xff;
j = (j + k3 + u) & 0xFF;
sj = s_data[(j/4)*32+threadIdx.x];
shiftj = 8*(j%4);
v = (sj >> shiftj) & 0xff;
si = (si & 0xffffff) | (v<<24);
sj = (sj & ~(0xFFu << (8*(j%4)))) | (u << shiftj);
s_data[(j/4)*32+threadIdx.x] = sj;
s_data[(i/4)*32+threadIdx.x] = si;
}
d_out[in] = s_data[threadIdx.x]; // unrelevant debug output
}
It seems the code at least partially involves re-ordering bytes. If you are using a Fermi-class GPU, you could look into using the __byte_perm() intrinsic which maps to a hardware instruction on Fermi-class devices and allows one to re-order bytes more efficiently.
I assume when you compare to other implementations it is apples-to-apples, i.e. on the same type of GPU. This code looks entirely compute bound, so the throughput will largely depend on the integer-instruction throughput of the GPU, and the performance spectrum is wide.
Given this Short (signed):
&Hxxxx
I want to:
Extract the most right &HxxFF as SByte (signed)
Extract the left &H7Fxx as Byte (unsigned)
Identify if the most left &H8xxx is positive or negative (bool result)
Extract the most right 0xxxff
myShort & 0x00FF
Extract the left 0xffxx
(myShort & 0xFF00) >> 8
Identify if the most left 0xfxxx is
positive or negative (it's a signed
short).
(myShort & 0xF000) >= 0;
Dim test As UInt16 = &HD 'a test value 1101
Dim rb As Byte 'lsb
Dim lb As Byte 'msb - 7 bits
Dim rm As UInt16 = &HFF 'lsb mask
Dim lm As UInt16 = &H7F00 'msb mask
Dim sgn As Byte = &H80 'sign mask
For x As Integer = 0 To 15 'shift the test value one bit at a time
rb = CByte(test And rm) 'get lsb
lb = CByte((test And lm) >> 8) 'get msb
Dim lbS, rbS As Boolean 'sign
'set signs
If (rb And sgn) = sgn Then rbS = True _
Else rbS = False
If (lb And sgn) = sgn Then lbS = True _
Else lbS = False 'should always be false based on mask
Console.WriteLine(String.Format("{0} {1} {2} {3} {4}",
x.ToString.PadLeft(2, " "c),
Convert.ToString(lb, 2).PadLeft(8, "0"c),
Convert.ToString(rb, 2).PadLeft(8, "0"c),
lbS.ToString, rbS.ToString))
test = test << 1
Next
inline char getLsb(short s)
{
return s & 0xff;
}
inline char getMsb(short s)
{
return (s & 0xff00) >> 8;
}
inline bool isBitSet(short s, unsigned pos)
{
return (s & (1 << pos)) > 0;
}
Uh...
value & 0x00ff
(value & 0xff00) >> 8
(value & 0xf000) >= 0
EDIT: I suppose you want the byte value and not just the upper 8 bits.
Extract the most right &HxxFF as SByte (signed)
CType(s AND &H00FF, SByte)
Extract the left &H7Fxx as Byte (unsigned)
CType((s AND &H7F00) >> 8, Byte)
Identify if the most left &H8xxx is positive or negative (bool result)
s AND &H8000 > 0
I think those work, been a while since I have worked in VB