Marco Gasi
asked on
dynamic array and variant record
Hi all. I'll try to explain my problem. In order to hide some sensitive string
in a my program, I use a tecnique I don't know hot to call it, so I describe it.
I declare a record this way:
Obviously the arry's length depends on the string length. Then, supposing the
string is s:
This way I can refer to the string using r.s and the cracker has to work a lot more
to break my code.
Since I have yet changed several times the string to mask this way (it is the
url for convalidation the software license), I thought to make a little utility
to allow me to simply tyoe the string and output the record values to use in my code.
For the above example this code is:
The r.s is 'IDontKnowHowToDoItButIHop eYouCanHel pMeEasilyA ndSoon'.
Only problem is that I wish only type a string, and click a button without the
need to change the record declaration every time.
I tried to make the two arrays dynamic but I received this error:
"Type 'dynamic array' needs finalization - not alloweed in variant record".
How can I solve this' Have you a workaround?
Thanks in advance for any try to help me
in a my program, I use a tecnique I don't know hot to call it, so I describe it.
I declare a record this way:
Rec = record
case Boolean of
False: (s: array[0..51] of AnsiChar);
True: (i: array[0..12] of Integer);
end;
Obviously the arry's length depends on the string length. Then, supposing the
string is s:
procedure TForm2.btnCreateStringClick(Sender: TObject);
var
r: Rec;
s: AnsiString;
I: Integer;
code, value: string;
begin
//da stringa a Cardinal
FillChar(r.s, SizeOf(r.s), 0);
s := 'IDontKnowHowToDoItButIHopeYouCanHelpMeEasilyAndSoon';
Move(PAnsiChar(s)^, r.s, Length(s));
for I := Low(r.i) to High(r.i) do
begin
value := IntToStr(not(r.i[I] shl 1));
mmoString.Lines.Add('r.i['+ IntToStr(I) +'] := Cardinal(not ' + value + ') shr 1;');
end;
end;
This way I can refer to the string using r.s and the cracker has to work a lot more
to break my code.
Since I have yet changed several times the string to mask this way (it is the
url for convalidation the software license), I thought to make a little utility
to allow me to simply tyoe the string and output the record values to use in my code.
For the above example this code is:
r.i[0] := Cardinal(not 521606959) shr 1;
r.i[1] := Cardinal(not 933339531) shr 1;
r.i[2] := Cardinal(not 790570805) shr 1;
r.i[3] := Cardinal(not 924924205) shr 1;
r.i[4] := Cardinal(not -1557060819) shr 1;
r.i[5] := Cardinal(not 296035637) shr 1;
r.i[6] := Cardinal(not 765672245) shr 1;
r.i[7] := Cardinal(not 758358295) shr 1;
r.i[8] := Cardinal(not -1592183513) shr 1;
r.i[9] := Cardinal(not 1027022613) shr 1;
r.i[10] := Cardinal(not -1592183529) shr 1;
r.i[11] := Cardinal(not 252786489) shr 1;
r.i[12] := Cardinal(not 924784035) shr 1;
The r.s is 'IDontKnowHowToDoItButIHop
Only problem is that I wish only type a string, and click a button without the
need to change the record declaration every time.
I tried to make the two arrays dynamic but I received this error:
"Type 'dynamic array' needs finalization - not alloweed in variant record".
How can I solve this' Have you a workaround?
Thanks in advance for any try to help me
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for your answer, epasquier. I'll try it as soon as possible - now I have to prepare my wedding anniversary and I can stay no more at the beloved computer ;-)
Only a thing. You simplified the Move statement but you didn't use it in your code: your code doesn't need it? Or I have to merge my code with yours?
'See' you later...
Only a thing. You simplified the Move statement but you didn't use it in your code: your code doesn't need it? Or I have to merge my code with yours?
'See' you later...
no need to merge anything, take just my code
I only started with a comment on Move because obviously you didn't knew how to perform it that way.
Good Wedding Anniversary !
I only started with a comment on Move because obviously you didn't knew how to perform it that way.
Good Wedding Anniversary !
A night of love one never forgets...
ASKER
Thanks a lot for your help, epasquier. It works very fine :-)
ASKER
Hi, epasquier. Are you still monitoring this question? I have a little problem: I can't copy and past the output of your code because Delphi7 doesn't compile it. Suppose string is 'Pippo'; The output is
DecodeString(Pippo,[
4294967135,4294967085,4294 967071,429 4967071,42 94967073]) ;
Thisis wrong, because DecodeString procedure requires the first parameter be and EncodedString and the second one an AnsiString. I tried to change this way
DecodeString([
4294967135,4294967085,4294 967071,429 4967071,42 94967073], s);
But with this code I receive this error: 'Constants expression violates subrange bounds'
I tried several ways, with quotes, without brackets and so on but I didn't succeed. Can youhelp me?
DecodeString(Pippo,[
4294967135,4294967085,4294
Thisis wrong, because DecodeString procedure requires the first parameter be and EncodedString and the second one an AnsiString. I tried to change this way
DecodeString([
4294967135,4294967085,4294
But with this code I receive this error: 'Constants expression violates subrange bounds'
I tried several ways, with quotes, without brackets and so on but I didn't succeed. Can youhelp me?
ok, my bad you cannot pass array of Cardinal like that. Only 'array of const' can be but it's more complex. Let's build a var EncConst of type EncodedString instead and pass it (first parameter, I made also an error here)
procedure WriteDecodingCode(const StrVarName:String;const Enc:EncodedString);
Var
i:integer;
begin
if Length(Enc)=0 Then Exit; // prevent errors
mmoString.Lines.Add('SetLength(EncConst,'+IntToStr(Length(Enc))+');');
for i:=0 to Length(Enc)-1 do
mmoString.Lines.Add(Format('EncConst[%d]=%d',[i,Enc[i]]));
mmoString.Lines.Add('DecodeString(EncConst,'+StrVarName+');');
end;
ASKER
Hi, epasquier. Thank you for trying to help me and I'm sorry to waste your time, but that doesn't work.
The result is
SetLength(EncConst,5);
EncConst[0]=-161
EncConst[1]=-211
EncConst[2]=-225
EncConst[3]=-225
EncConst[4]=-223
DecodeString(EncConst,pipp o);
The problem is syntactical and I fixed that making this
SetLength(EncConst,5);
EncConst[0]:=-161;
EncConst[1]:=-211;
EncConst[2]:=-225;
EncConst[3]:=-225;
EncConst[4]:=-223;
DecodeString(EncConst,s);
where s is an empty string which will holds the decoded value (It's right this?). Unfortunately I still receive the same error message: 'Constants expression violates subrange bounds'
Thanks a lot.
The result is
SetLength(EncConst,5);
EncConst[0]=-161
EncConst[1]=-211
EncConst[2]=-225
EncConst[3]=-225
EncConst[4]=-223
DecodeString(EncConst,pipp
The problem is syntactical and I fixed that making this
SetLength(EncConst,5);
EncConst[0]:=-161;
EncConst[1]:=-211;
EncConst[2]:=-225;
EncConst[3]:=-225;
EncConst[4]:=-223;
DecodeString(EncConst,s);
where s is an empty string which will holds the decoded value (It's right this?). Unfortunately I still receive the same error message: 'Constants expression violates subrange bounds'
Thanks a lot.
Cardinal is unsigned int, so I guess the format function treats it as Integer. Just declare
Type
EncodedString=Array of Integer;
ASKER
Yeah, now it works fine! Thank you very mutch for your help. On to the next. :-)
Var
Enc:EncodedString;
begin
EncodeString(edtStringToEn
WriteDecodingCode( edtStringVarName.Text, Enc );
end;
and include DecodeString in your target application