Recent

Author Topic: Python struct.pack equivalent anyone?  (Read 4053 times)

cday

  • Newbie
  • Posts: 4
Python struct.pack equivalent anyone?
« on: July 15, 2018, 04:40:34 am »
Hi.

I'm trying to replicate this python code:

Code: Pascal  [Select][+][-]
  1. record = struct.pack("ABC", "123456","12" + (option <<20)

where 'option' in above is an int from 1 to 1000

Hoping someone familiar with python can explain whats going on and how I go about replicating this is Lazarus..

Windsurfer

  • Sr. Member
  • ****
  • Posts: 368
    • Windsurfer

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Python struct.pack equivalent anyone?
« Reply #2 on: July 15, 2018, 08:37:16 am »
Well, it is not as easy as you think (because of memory layout in Python and type(lessness)). But a probably non-compatible Pascal version would look like this:
[edit see also windsurfer's link, posts crossed.]
Code: Pascal  [Select][+][-]
  1. {$ifdef fpc}{$mode delphi}{$endif}
  2. program project1;
  3. type
  4.   TMyrecord = packed record
  5.      S:array[0..2] of char;
  6.      L1:cardinal;
  7.      L2:cardinal;
  8.   end;
  9. var
  10.   Option:Integer = 1;
  11.   R:Tmyrecord;
  12. begin
  13.   R.S:='ABC';
  14.   R.L1:=123456;
  15.   R.L2:=12 + option shl 20;
  16.   writeln(R.s,R.L1,R.L2);
  17. end.
It does not likely have the same memory lay-out. Pascal is more efficient.
« Last Edit: July 15, 2018, 10:08:31 am by Thaddy »
Specialize a type, not a var.

cday

  • Newbie
  • Posts: 4
Re: Python struct.pack equivalent anyone?
« Reply #3 on: July 15, 2018, 02:08:31 pm »
A huge thank you Thaddy! I'll try it later & report back..

bytebites

  • Hero Member
  • *****
  • Posts: 633
Re: Python struct.pack equivalent anyone?
« Reply #4 on: July 15, 2018, 08:18:33 pm »
The first string "ABC" is formatting string.

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Python struct.pack equivalent anyone?
« Reply #5 on: July 15, 2018, 09:28:38 pm »
Nope. It is a valid assignment to an array of three chars.....< very grumpy now... >:D >:D >:D >:D >:D >:D >:D >

The sizeof() is proof of that: no overhead. Size is 3+4+4 = 11.
« Last Edit: July 15, 2018, 09:37:41 pm by Thaddy »
Specialize a type, not a var.

bytebites

  • Hero Member
  • *****
  • Posts: 633
Re: Python struct.pack equivalent anyone?
« Reply #6 on: July 15, 2018, 09:46:41 pm »
Python doc says:
Quote
struct.pack(format, v1, v2, ...)
Return a bytes object containing the values v1, v2, … packed according to the format string format. The arguments must match the values required by the format exactly.
Besides the format string is faulty.

Code: Python  [Select][+][-]
  1. "12" + (option <<20)
Does not work even in Python

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: Python struct.pack equivalent anyone?
« Reply #7 on: July 15, 2018, 09:55:47 pm »
Well, my Pascal code works.(And that code works in Python, at least I checked, had to write a little full program, but it works)
Prove me wrong: you can't.... Simple as that.
Specialize a type, not a var.

bytebites

  • Hero Member
  • *****
  • Posts: 633
Re: Python struct.pack equivalent anyone?
« Reply #8 on: July 15, 2018, 09:59:39 pm »
>>> option=2
>>> "12" + (option <<20)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly

Working code for Python, which writes only 8 bytes not 11.
Code: Python  [Select][+][-]
  1. import struct
  2.  
  3. option=2;
  4. record = struct.pack("ii", 123456,12 + (option <<20))
  5. with open("foo","wb") as f:
  6.    f.write(record)
  7.  
« Last Edit: July 15, 2018, 10:42:19 pm by bytebites »

cday

  • Newbie
  • Posts: 4
Re: Python struct.pack equivalent anyone?
« Reply #9 on: July 17, 2018, 12:06:01 pm »
FWIW, this is the full python script I'm trying to replicate in Lazarus:
Code: Pascal  [Select][+][-]
  1. from Crypto.Cipher import ARC2
  2. import struct
  3.  
  4. serial = 100377
  5. serial2 = 30
  6. option = 56
  7. record = struct.pack("<II", serial, serial2 + (option <<20))
  8. encyphered = ARC2.new("Revision\0").encrypt(record)
  9. print encyphered.encode("hex")
  10.  

But I'm having issues trying to work out how to implement it using FPC crypto classes. From what I have read, ARC2 is the same as RC2. I've had a play but really have not much idea what I'm doing..

cday

  • Newbie
  • Posts: 4
Re: Python struct.pack equivalent anyone?
« Reply #10 on: July 17, 2018, 12:10:15 pm »
Oh the output from that bit of python code is 07b1a8b9122b6f2d

ricardo_sdl

  • New Member
  • *
  • Posts: 21
Re: Python struct.pack equivalent anyone?
« Reply #11 on: July 17, 2018, 09:47:35 pm »
You can write the bytes of the record directly like this:
Code: Pascal  [Select][+][-]
  1. {$Mode ObjFpc}{$H+}{$J-}
  2. program Foo;
  3.  
  4. uses Classes, sysutils;
  5.  
  6. type
  7.   TFoo = packed record
  8.     serial: LongWord;
  9.     serial2: LongWord;
  10.   end;
  11.  
  12. var
  13.   MyFoo: TFoo;
  14.   Option: LongWord;
  15.   FileHandle: THandle;
  16. begin
  17.  
  18.   MyFoo.serial := 100377;
  19.   Option := 56;
  20.   MyFoo.serial2 := 30 + (Option shl 20);
  21.  
  22.  
  23.   FileHandle := FileCreate('./FooFile');
  24.  
  25.   FileWrite(FileHandle, MyFoo, SizeOf(MyFoo));
  26.  
  27.   FileClose(FileHandle);
  28.  
  29. end.
  30.  

 

TinyPortal © 2005-2018