Solved

dynamic array and variant record

Posted on 2011-09-16
10
373 Views
Last Modified: 2012-05-12
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:
Rec = record
      case Boolean of
        False: (s: array[0..51] of AnsiChar);
        True: (i: array[0..12] of Integer);
    end;

Open in new window


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;

Open in new window


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;

Open in new window


The r.s is 'IDontKnowHowToDoItButIHopeYouCanHelpMeEasilyAndSoon'.

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
0
Comment
Question by:Marco Gasi
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 5
10 Comments
 
LVL 25

Accepted Solution

by:
epasquier earned 500 total points
ID: 36550468
first :
Move(PAnsiChar(s)^, r.s, Length(s));
=
Move(s[1], r.s, Length(s));

then, it can be simplified a bit
Type
 EncodedString=Array of Cardinal;

procedure EncodeString(Str:AnsiString;Var R:EncodedString);
Var
 i:integer;
begin
 SetLength(R,Length(Str));
 for i:=1 to Length(Str) do R[i-1]:=Not(Byte(Str[i]) SHL 1);
end;

procedure DecodeString(const R:EncodedString;Var Str:AnsiString);
Var
 i:integer;
begin
 SetLength(Str,Length(R));
 for i:=1 to Length(Str) do Str[i]:=AnsiChar((Not R[i-1]) SHR 1);
end;

procedure WriteDecodingCode(const StrVarName:String;const Enc:EncodedString);
Var
 EncConstArray:String;
 i:integer;
begin
 if Length(Enc)=0 Then Exit; // prevent errors
 mmoString.Lines.Add('DecodeString('+StrVarName+',[');
 EncConstArray:='';
 for i:=0 to Length(Enc)-1 do EncConstArray:=EncConstArray+IntToStr(Enc[i])+',';
 EncConstArray[Length(EncConstArray)]:=']'; // replace last ',' with ']'
 mmoString.Lines.Add(EncConstArray+');');
end;

Open in new window

0
 
LVL 25

Expert Comment

by:epasquier
ID: 36550493
so, in your encoding tool application :

Var
 Enc:EncodedString;
begin
 EncodeString(edtStringToEncode.Text, Enc );
 WriteDecodingCode( edtStringVarName.Text, Enc );
end;

and include DecodeString in your target application
0
 
LVL 31

Author Comment

by:Marco Gasi
ID: 36550527
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...
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 25

Expert Comment

by:epasquier
ID: 36550542
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 !

A night of love one never forgets...
0
 
LVL 31

Author Closing Comment

by:Marco Gasi
ID: 36554347
Thanks a lot for your help, epasquier. It works very fine :-)
0
 
LVL 31

Author Comment

by:Marco Gasi
ID: 36554887
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,4294967071,4294967071,4294967073]);

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,4294967071,4294967071,4294967073], 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?
0
 
LVL 25

Expert Comment

by:epasquier
ID: 36555167
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;

Open in new window

0
 
LVL 31

Author Comment

by:Marco Gasi
ID: 36555581
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,pippo);

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.
0
 
LVL 25

Expert Comment

by:epasquier
ID: 36555731
Cardinal is unsigned int, so I guess the format function treats it as Integer. Just declare
Type
 EncodedString=Array of Integer;

Open in new window

0
 
LVL 31

Author Comment

by:Marco Gasi
ID: 36556090
Yeah, now it works fine! Thank you very mutch for your help. On to the next. :-)
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Strange behavior when a form is closed 6 77
Microsoft Access 97 and Delphi XE2 9 85
Delphi, TImage, Png 2 53
Firemonkey Queue list 1 51
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…

732 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question