I’m trying to convert this Delphi code to C#
function TWebModule1.DecodeA(Auth: string): Word;
var
iAuth: Cardinal;
r: Cardinal;
begin
iAuth := StrToInt64(Auth);
r := (iAuth and $FFFF0000) shr 16;
Result := (iAuth and $FFFF) xor r xor $9752;
end;
Here is what I have written in C# but it’s not giving me the expected results.
private Int64 DecodeA(Int64 auth)
{
try
{
var r = (auth & 0xFFFF0000) >> 16;
var result = (auth & 0xFFFF) ^ r ^ 0x9752;
_log.DebugFormat("Decoding of {0} returned {1}", auth, result);
return result;
}
catch (Exception ex)
{
_log.Fatal(ex);
throw new Exception(ex.Message);
}
}
Example:auth = 3216841950 should have a result of 41022
Thank you for any information you provide.
If you use the same datatypes in both languages then it works just out of the box:
Delphi version
function DecodeA(iAuth: Int64): Int64;
var
r: Int64;
begin
r := (iAuth and $FFFF0000) shr 16;
Result := (iAuth and $FFFF) xor r xor $9752;
end;
C# version
private Int64 DecodeA(Int64 iAuth)
{
Int64 r = (iAuth & 0xFFFF0000) >> 16;
return (iAuth & 0xFFFF) ^ r ^ 0x9752;
}
In both languages DecodeA(3216841950) equals 13361
The key understanding this it to know why the Delphi developer chose to use StrToInt64 considering that the rest of the code operates on 32 bit integers. The reason for this is that StrToInt returns a signed 32 bit integer, and so for values in the range 2^31 to 2^32 - 1 results in an error. The developer of the original Delphi code handled this by treating the input as a 64 bit integer, a data type that includes the complete range of a 32 bit unsigned type.
Now, in your C# code you can translate it very literally, but you don't need to use 64 bit types, just as the Delphi code does not. The Delphi code operates on 32 bit unsigned integers, and returns a 16 bit unsigned integer.
ushort DecodeA(uint iauth)
{
uint r = (iauth & 0xffff0000) >> 16;
return (ushort) (iauth & 0xffff) ^ r ^ 0x9752;
}
ushort DecodeA(string auth)
{
return DecodeA(uint.Parse(auth));
}
Here I have provided two overloads, one for string input which parses the string, and one receives an unsigned 32 bit integer as input. The former calls the latter.
Note that I have followed the lead of the Delphi code and returned a 16 bit unsigned integer, ushort.
Related
I'm actualy trying to convert pascal code into c# code (we are re-writing old application).
Pascal code:
function DecryptStr(Source: PChar): string;
var
st: string;
i, k, mask: byte;
begin
Result := '';
try
SetString(st, Source, 32);
if st[1] <> #0 then
begin
mask := ord(st[1]);
k := ord(st[2]) xor mask;
SetLength(Result, k);
for i := 1 to k do
begin
inc(mask);
k := ord(st[i + 2]) xor mask;
Result[i] := chr(k);
// Result := Result + chr(k);
end;
end;
except
end;
end;
And my C# code:
public static string decrypt(string hash)
{ string buffer;
byte i, k, mask;
string result = "";
buffer = hash.Substring(0, 32);
mask = (byte)(buffer[0]);
k = (byte)((byte)(buffer[1])^mask);
for (i = 0; i<k-1; i++)
{
mask += 1;
k = (byte)((byte)(buffer[i+2])^mask);
result+=(char)(k);
}
// string decoded = System.
return (result);
}
Please, tell me, is it similar or pascal got some hidden stuff?
Example:
input in c#:
акРЖђЏГ€€њљђНѓGН q6™&і—'n1•\›ЛH[
output in c#:
\u0011$\f\v&\t\b
But it doesnt look like the real password.
Please, advice me what is going wrong.
The problem was in two things:
PChar format of input string - means it stores "0" at the end.
Idiotic mechanism of encryption - actualy, the guy who wrote down the code represented in question just chosed byte mask as a rand(200) + 32 was storing it in first byte of encrypted pass and then in cycle he was incrementing mask by one every step for all of pass length.
So the logic of decrypting is following:
Grab the mask - buffer[0] in this case
Do XOR for every other character with this mask, increasing it by one on every step.
3.???
Profit!
Thanks for everyone who participated in this theme!
Parameters: InLong = 0, Posit = 5, and from an ASCII file TmPChar{.,STX,NUL,NUL}
Delphi code
Procedure TForm1.GetLongFromBuf(Var InLong : Longint; Posit : Integer; ZRepB : ZrepBuf);
Var
TmpPChar : Array[0..3] Of Char;
PLong : ^Longint;
I : Byte;
Begin
For I:= 0 To 3 Do
TmpPChar[I] := ZRepB[Posit+I];
PLong := #TmpPChar;
InLong := PLong^;
End;
Outputs: TmPChar {'.', #2, #0, #0}, PLong = 13F54C, InLong = 558
C# code
unsafe static long GetLongFromBuf(long InLong, int Posit, char[] ZRepB){
long* Plong;
char[] TmpPChar = new char[4];
for (byte i = 0; i < TmpPChar.Length; i++){
TmpPChar[i] = ZRepB[(Posit-1) + (i)];
}
fixed(char* ch = TmpPChar){
PLong = (long*)&ch;
InLong ^= (long)PLong;
}
return InLong;
}
Outputs: TmPChar{'.','\u0002','\0','0'}, PLong = 0x0000000000b3cc18, InLong = 11783192
It appears that you are using this Delphi code without really understanding what it is doing. From your results, we can conclude you are using a pre-unicode version of Delphi (ie: D2007 or earlier). We can also guess that ZrepBuf is defining an array of bytes or [Ansi]Char. The method, then, works as follows :
For I:= 0 To 3 Do
TmpPChar[I] := ZRepB[Posit+I]; /* Copy four sequential bytes to TmpPChar array */
PLong := #TmpPChar; /* Take a pointer to the head of the array */
InLong := PLong^; /* Dereference the pointer, interpreting as a 32-bit int */
This is code to convert four bytes to a 32-bit integer. In Delphi the LongInt type is an alias for the 32-bit integer type, equivalent to the int type in C#, not long. There is no use of the XOR operator in the Delphi code. In PLong^, the ^ operator is a dereference operation.
In C# you can avoid unsafe code entirely and simply perform this conversion using the BitConverter class:
byte[] b = new byte[4] { 0x2E, 0x02, 0x00, 0x00 };
int result = BitConverter.ToInt32(b, 0); // result == 558
Here I've defined the input array as a byte[] since a char in C# (and in Delphi 2009 or newer) is a 16-bit type (two bytes) for storing Unicode characters. The data you are reading is ANSI encoded - I'm presuming you understand how to read your text file into a byte array.
Incidentally, in more modern Delphi you could also re-write the pointer code above to use the TEncoding class to perform this function as described here in a similar way to the BitConverter class in C#.
I am trying to convert this pascal code into C# in order to communicate with a peripheral device attached to a comm port. This piece of code should calculate the Control Byte, however I'm not getting the right hex Value therefore I'm wondering if I'm converting the code in the right way.
Pascal:
begin
check := 255;
for i:= 3 to length(sequence)-4 do
check := check xor byte(sequence[i]);
end;
C#:
int check = 255;
for (int x = 3; x < (sequence.Length - 4); x++)
{
check = check ^ (byte)(sequence[x]);
}
Pascal function:
{ *** conversion of number into string ‘hex’ *** }
function word_to_hex (w: word) : string;
var
i : integer;
s : string;
b : byte;
c : char;
begin
s := ‘’;
for i:= 0 to 3 do
begin
b := (hi(w) shr 4) and 15;
case b of
0..9 : c := char(b+$30);
10..15 : c := char(b+$41-10);
end;
s := s + c;
w := w shl 4;
end;
word_ to_hex := s;
end;
C# Equivalent:
public string ControlByte(string check)
{
string s = "";
byte b;
char c = '\0';
//shift = check >> 4 & 15;
for (int x = 0; x <= 3; x++)
{
b = (byte)((Convert.ToInt32(check) >> 4) & 15);
if (b >= 0 && b <= 9)
{
c = (char)(b + 0x30);
}
else if (b >= 10 && b <= 15)
{
c = (char)(b + 0x41 - 10);
}
s = s + c;
check = (Convert.ToInt32(check) << 4).ToString();
}
return s;
}
And last pascal:
function byte_to_hex (b:byte) : string;
begin
byte_to_hex := copy(word_to_hex(word(b)),3,2);
end;
which i am not sure how is substringing the result from the function. So please let me know if there is something wrong with the code conversion and whether I need to convert the function result into bytes. I appreciate your help, UF.
Further info EDIT: Initially I send a string sequence containing the command and information that printer is supposed to print. Since every sequence has a unique Control Byte (in Hex) I have to calculate this from the sequence (sequence = "P1;1$l201PrinterPrinterPrinter1B/100.00/100.00/0/\") which is what upper code does according to POSNET=>"cc – control byte, encoded as 2 HEX digits (EXOR of all characters after ESC P to this byte with #255 initial quantity), according to the following algorithm in PASCAL language:(see first code block)".=>1. check number calculated in the above loop which constitutes control byte should be recoded into two HEX characters (ASCII characters from scope: ‘0’..’9’,’A’..’F’,’a’..’f’), utilizing the following byte_to_hex function:(see third code block). =>{* conversion of byte into 2 characters *}(see 5th code block)
The most obvious problem that I can see is that the Pascal code operates on 1-based 8 bit encoded strings, and the C# code operates on 0-based 16 bit encoded strings. To convert the Pascal/Delphi code that you use to C# you need to address the mis-match. Perhaps like this:
byte[] bytes = Encoding.Default.GetBytes(sequence);
int check = 255;
for (int i = 2; i < bytes.Length-4; i++)
{
check ^= bytes[i];
}
Now, in order to write this I've had to make quite a few assumptions, because you did not include anywhere near enough code in the question. Here's what I assumed:
The Pascal sequence variable is a 1-based 8 bit ANSI encoded Delphi AnsiString.
The Pascal check variable is a Delphi 32 bit signed Integer.
The C# sequence variable is a C# string.
If any of those assumptions prove to be false, then the code above will be no good. For instance, perhaps the Pascal check is really Byte. In which case I guess the C# code should be:
byte[] bytes = Encoding.Default.GetBytes(sequence);
byte check = 255;
for (int i = 2; i < bytes.Length - 4; i++)
{
check ^= bytes[i];
}
I hope that this persuades you of the importance of supplying complete information.
That's really all the meat of this question. The rest of the code concerns converting values to hex strings in C# code. That has been covered again and again here on Stack Overflow. For instance:
C# convert integer to hex and back again
How do you convert Byte Array to Hexadecimal String, and vice versa?
There are many many more such questions.
I'm trying to port a C++ function that uses Bitwise operations to C#, but am running into issues. Namely when the input is 0x01123456 the C# returns zero, but it should be 12
BN_set_word and other BN_* functions are in OpenSSL. What do these functions do (in detail) ... Is there a .NET equivalent in big integer?
What is an MPI representation? (google is of no use)
Should I be concerned about Masking in the shift count as mentioned in the comments here?
C++ Original
Git Source
// The "compact" format is a representation of a whole
// number N using an unsigned 32bit number similar to a
// floating point format.
// The most significant 8 bits are the unsigned exponent of base 256.
// This exponent can be thought of as "number of bytes of N".
// The lower 23 bits are the mantissa.
// Bit number 24 (0x800000) represents the sign of N.
// N = (-1^sign) * mantissa * 256^(exponent-3)
//
// Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn().
// MPI uses the most significant bit of the first byte as sign.
// Thus 0x1234560000 is compact (0x05123456)
// and 0xc0de000000 is compact (0x0600c0de)
// (0x05c0de00) would be -0x40de000000
//
// Bitcoin only uses this "compact" format for encoding difficulty
// targets, which are unsigned 256bit quantities. Thus, all the
// complexities of the sign bit and using base 256 are probably an
// implementation accident.
//
// This implementation directly uses shifts instead of going
// through an intermediate MPI representation.
CBigNum& SetCompact(unsigned int nCompact)
{
unsigned int nSize = nCompact >> 24;
bool fNegative =(nCompact & 0x00800000) != 0;
unsigned int nWord = nCompact & 0x007fffff;
if (nSize <= 3)
{
nWord >>= 8*(3-nSize);
BN_set_word(this, nWord);
}
else
{
BN_set_word(this, nWord);
BN_lshift(this, this, 8*(nSize-3));
}
BN_set_negative(this, fNegative);
return *this;
}
C# attempted port
internal static System.Numerics.BigInteger SetCompact(uint numToCompact)
{
//
//
// SetCompact
// Extract the number from bits 0..23
uint nWord = numToCompact & 0x007fffff;
BigInteger ret = new BigInteger(nWord);
// Add zeroes to the left according to bits 25..32
var ttt = ret.ToByteArray();
uint size = numToCompact >> 24;
uint amountToShift = 0;
if (size <= 3)
{
amountToShift = 8 * (3 - size);
ret = ret >> (int)amountToShift;
}
else
{
ret = ret << (int)amountToShift;
amountToShift = 8 * (size - 3);
}
// Set the value negative if required per bit 24
UInt32 isNegative = 0x00800000 & numToCompact;
if (isNegative != 0)
ret =BigInteger.Negate(ret);
var test = ret.ToByteArray();
Console.WriteLine();
Console.WriteLine(ret.ToString("X"));
return ret;
}
What is the equivalent (in C#) of Java's >>> operator?
(Just to clarify, I'm not referring to the >> and << operators.)
Edit: The Unsigned right-shift operator >>> is now also available in C# 11 and later.
For earlier C# versions, you can use unsigned integer types, and then the << and >> do what you expect. The MSDN documentation on shift operators gives you the details.
Since Java doesn't support unsigned integers (apart from char), this additional operator became necessary.
Java doesn't have an unsigned left shift (<<<), but either way, you can just cast to uint and shfit from there.
E.g.
(int)((uint)foo >> 2); // temporarily cast to uint, shift, then cast back to int
Upon reading this, I hope my conclusion of use as follows is correct.
If not, insights appreciated.
Java
i >>>= 1;
C#:
i = (int)((uint)i >> 1);
n >>> s in Java is equivalent to TripleShift(n,s) where:
private static long TripleShift(long n, int s)
{
if (n >= 0)
return n >> s;
return (n >> s) + (2 << ~s);
}
There is no >>> operator in C#. But you can convert your value like int,long,Int16,Int32,Int64 to unsigned uint, ulong, UInt16,UInt32,UInt64 etc.
Here is the example.
private long getUnsignedRightShift(long value,int s)
{
return (long)((ulong)value >> s);
}
C# 11 and later supports >>> Unsigned right shift operator
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators#unsigned-right-shift-operator-
For my VB.Net folks
The suggested answers above will give you overflow exceptions with Option Strict ON
Try this for example -100 >>> 2 with above solutions:
The following code works always for >>>
Function RShift3(ByVal a As Long, ByVal n As Integer) As Long
If a >= 0 Then
Return a >> n
Else
Return (a >> n) + (2 << (Not n))
End If
End Function