Byte to String in Delphi - c#

I want to convert a Byte to String in Delphi
in c# for example is:
Convert.ToString(Byte, 16);
I tried:
SetString(AnsiStr, PAnsiChar(#ByteArray[0]), LengthOfByteArray);
StringVar := Chr(ByteVar);
Thanks

Assuming that Byte is a placeholder for a value of type byte, your C# code converts a single byte to its hexadecimal representation. The Delphi equivalent is IntToHex.
var
s: string;
b: Byte;
....
b := ...;
s := IntToHex(b);
Your Delphi code hints at you actually wishing to convert an array of bytes to their hexadecimal representation. In which case the function you need is BinToHex. I can't really give you much more detail because your question itself was lacking in detail. Without knowledge of the types of the variables, we are left making guesses. In future questions, it would be wise to supply a Minimal, Complete, and Verifiable example.

Finally I use this function;
function TForm1.bintostr(const bin: array of byte): string;
const HexSymbols = '0123456789ABCDEF';
var i: integer;
begin
SetLength(Result, 2*Length(bin));
for i := 0 to Length(bin)-1 do begin
Result[1 + 2*i + 0] := HexSymbols[1 + bin[i] shr 4];
Result[1 + 2*i + 1] := HexSymbols[1 + bin[i] and $0F];
end;
end;

Related

Pascal code to C# code conversion (ord and chr)

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!

Can't get the same result as the Delphi code, after I exclusive-OR an address of a char array in C#

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#.

Delphi function to C#

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.

Pascal to C# conversion

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.

How to convert some C# code to Pascal?

I have a couple of functions that I need to convert to Pascal to include in my inno setup installer, to validate a serial number on install.
Any assistance would be appreciated, as I haven't written any pascal in about 8 years.
Here is the C# code.
public static long DecodeAuthID(String keyset, String toDecode)
{
StringBuilder retval = new StringBuilder();
for (int i = 0; i < toDecode.Length; i++)
{
char[] toDecodeCharArray = toDecode.ToCharArray();
retval.Append(keyset.IndexOf(toDecodeCharArray[i]));
}
return Int32.Parse(retval.ToString());
}
public static string ReverseString(string stringToReverse)
{
char[] values = stringToReverse.ToCharArray();
Array.Reverse(values);
return new string(values);
}
private static void GetLocationFromAuthenticationID()
{
// Get Authentication Key from the Registry
string registryValue = GetAuthIDFromRegistry();
// Decode the Authentication Key to get the location
string value1 = ReverseString(registryValue);
string value2 = value1.Substring(0, 12);
string keyset = ReverseString(value2);
string valuesReversed = value1.Substring(12, value1.Length - 12);
string values = ReverseString(valuesReversed);
// Decode the AuthID
string authID = DecodeAuthID(keyset, values).ToString();
// Convert to Location ID
int locationID = Int32.Parse(authID) - (Int32.Parse(authID) - 1);
}
You can take a look at this (untested, other than it compiles if I comment out the line with GetAuthIDFromRegistry which is unimplemented - couldn't test because I don't have any sample input/output data to work with from your question). It may not be 100% correct, but it should at least get you started in the right direction.
function DecodeAuthID(KeySet: string; toDecode: string): longint;
var
idx, c: Integer;
Temp: string;
begin
Temp := '';
for idx := 1 to Length(toDecode) do
begin
// Replaces keyset.IndexOf. Handles no match found in KeySet just in case.
c := Pos(toDecode[idx], KeySet);
if c > 0 then
Temp := Temp + KeySet[c];
end;
// Handles no values set in result by returning 0
Result := StrToIntDef(Temp, 0);
end;
function ReverseString(stringToReverse: string): string;
var
i: Integer;
begin
Result := '';
for i := 1 to Length(stringToReverse) do
Result := stringToReverse[i] + Result;
end;
procedure GetLocationFromAuthenticationID;
var
registryValue: string;
value1, value2, keyset: string;
valuesReversed: string;
values: string;
authID: LongInt;
locationID: Integer;
begin
// GetAuthIDFromRegistry code not provided in question.
// See InnoSetup Help File, Pascal Scripting: Support Functions Reference,
// subheading "Registry functions"
registryValue := GetAuthIDFromRegistry;
value1 := ReverseString(registryValue);
// Delphi strings are 1 based, as opposed to the C# char array's 0 base
value2 := Copy(value1, 1, 12);
keyset := ReverseString(value2);
valuesReversed := Copy(Value1, 13, Length(value1) - 12);
values := ReverseString(valuesReversed);
authID := DecodeAuthID(keyset, values);
locationID := authID - (authID - 1);
end;
All of the functions not containing source here are listed as supported in the InnoSetup help file in either the "Pascal Scripting: Support Functions Reference".
You can try the C# to Oxygene converter that does this conversion to Oxygene, the Object Pascal used in Delphi Prism.
The problem is that this code makes use of .NET classes (like StringBuilder) and converters (Int32.Parse) that are not available in InnoSetup.

Categories