Is the program 32 or 64 bits?

2

Assignment is simple to explain: write the shortest code you need to determine whether an executable binary program supplied as parameter is 32 or 64 bits.

If there is a different kind of bitness, you can also do for it, but is not mandatory.

What I really don't want is telling me you support other bitnesses and after I get 32 or 64 as a result.

Valid outputs for 32:

32
32bit
32bits
32 bit
32 bits

The same pattern for 64.

No accepted answer.

sergiol

Posted 2018-04-12T22:55:44.713

Reputation: 3 055

@Pandacoder: Choose one platform and indicate for what one you have done it. – sergiol – 2018-04-12T23:30:41.113

@fəˈnɛtɪk: I suggest something like a bitness program.exe command line, where bitness is a call to the code you wrote, and program.exe is the binary you just want to evaluate how many bits it is. BTW, great nick! – sergiol – 2018-04-12T23:39:00.907

Answers

5

Jelly on Linux, 6 bytes

5ịO×32

Try it online!

Usage note: the question says "write the shortest code you need to determine whether an executable binary program supplied as parameter", and that's exactly what you need to do here; supply the entire executable binary program as the parameter. Not its filename, the program itself. (I hope you have a fairly understanding shell!) The TIO link uses the shortest known ELF program Linux will run, by Brian Raiter as the example program.

Linux uses ELF as its executable format. It turns out that the fifth byte of an ELF program specifies the processor bitwidth it's designed for: 0x01 for a 32-bit program, or 0x02 for a 64-bit program. So all we have to do is extract the byte in question (5ị), convert it from a character to a number (O), and multiply by 32 (×32).

There's probably a language that can use this exact algorithm more succinctly, but I wanted to post this answer to demonstrate the algorithm.

ais523

Posted 2018-04-12T22:55:44.713

Reputation: 11

7Why is this a community wiki? – dylnan – 2018-04-13T04:29:46.907

1@dylnan: a) in the hope that people will stop worrying about reputation (including me!), b) in the hope that people will edit the answer if they see something wrong with it (this has actually happened on at least one answer I've submitted, and I was in favour of it). I dislike the whole ownership/scorekeeping/gamification attitude that Stack Exchange is trying to push, so community wiki is something of a perfect fit. (Also, I used to just delete my account every answer, but chat suggested that community wiki might work better, and it means I keep the ability to edit my answers.) – ais523 – 2018-04-13T19:17:08.060

I responded by upvoting your comment then realized you might not want that... Anyway, I see what you mean and respect that. – dylnan – 2018-04-13T19:18:58.140

2

Bash + common Linux utils, 18

  • 2 byte saved thanks to @Dennis.
file -|cut -c17-18

The input program piped in.

Try it online!

Digital Trauma

Posted 2018-04-12T22:55:44.713

Reputation: 64 644

2

MATL (Linux), 5 bytes

5)32*

Implicitly input entire program. Get fifth byte, multiply by 32.

Try it online!


As a bonus, here's an answer that works on most (but not all) Windows executables, for 20 bytes:

t'PE'Xf1)4+)100=Q32*

Try it online!

Find the PE signature (which would fail if there's an unusual DOS stub containing PE) and see if it is followed by d (100) two bytes later (which corresponds to x64, and thus would fail for other 64 bit architectures)

Sanchises

Posted 2018-04-12T22:55:44.713

Reputation: 8 530

Would this fail if there is PE somewhere else (e.g., in the DOS stub)? – user202729 – 2018-04-13T10:38:12.460

1The Windows version works for most 64-bit processors supported by the PE format, but not all. E.g. for Itanium the machine type is 0x0200, not 0x0264. – Peter Taylor – 2018-04-13T10:40:50.103

@PeterTaylor I only tested it on some local files. I suppose I can remove the Windows part – Sanchises – 2018-04-13T11:05:20.873

@user202729 It would indeed. – Sanchises – 2018-04-13T11:05:41.153

2

GolfScript for ELF (5 bytes)

4=32*

CJam for ELF (6 bytes)

q4=32*

or

q4=5m<

This is why I commented in the sandbox that "challenge" was not an appropriate description of this task.

Peter Taylor

Posted 2018-04-12T22:55:44.713

Reputation: 41 901

1

Windows Bash (with core util?), test PE32 vs PE32+; 37 bytes

file $1|grep -q 2+&&echo 64||echo 32

This is a bash script works on Windows Bash (bash in Ubuntu Linux Subsystem on Windows 10), which tell given *.exe file 32 bit or 64 bit.

Not yet tested on other platform, maybe it work.

tsh

Posted 2018-04-12T22:55:44.713

Reputation: 13 072

How can I claim this language? – tsh – 2018-04-13T02:10:20.480

1

Jelly (Windows), 24 bytes

ƈO
Ç64СUḣ4%⁹ḅ⁹_38ǹ¡×32

Hexdump:

00000000: 9c4f 7f0e 3634 0f00 55ed 3425 89d4 895f  .O..64..U.4%..._
00000010: 3338 0e81 0011 3332                      38....32

I have no idea why %⁹ is necessary, but it is.

Takes the whole executable from STDIN. Take from command line argument would definitely shorter but there is a (small) upper bound on the size.

Yes, Windows PE executable format is hard to parse. Also Jelly hates non-constant nilad.


ƈO

Link 1: Return the next byte value from stdin.

Ç64СUḣ4%⁹ḅ⁹

Read the 4-byte e_lfanew at offset 60 and convert it to an integer.

_38ǹ¡

Take the byte at (e_lfanew - 38) positions later which is the higher byte of the signature in the PE optional header, described here at the "optional header magic number" part.

×32

Multiply by 32. Get 32 for 32-bit executables (PE32) and 64 for PE32+.

user202729

Posted 2018-04-12T22:55:44.713

Reputation: 14 620

"there is a (small) upper bound on the size" if you mean there's an upper bound on TIO, then no, TIO does not define Jelly and you can probably still use it locally with large command-line arguments. – Erik the Outgolfer – 2018-04-13T10:40:00.673

@EriktheOutgolfer (at least on my Linux machine) sometimes I get a "command line too long" error for somewhat-large size. – user202729 – 2018-04-13T10:41:02.187

@EriktheOutgolfer All Linux machines place several limits on command invocation. The maximum length of a single command-line argument is a compile-time constant of the kernel, usually 32 times the page size, which is 4 KiB for x86_64. It should be possible to raise it by recompiling the kernel though, so it's ultimately arbitrary. – Dennis – 2018-04-13T15:12:58.477

@Dennis So it seems like it would still be valid for this solution to take via command-line arguments. – Erik the Outgolfer – 2018-04-13T15:17:28.287

1

Haskell, 36 35 bytes

fmap((32*).fromEnum.(!!4)).readFile

For the ELF format

Try it online!

Angs

Posted 2018-04-12T22:55:44.713

Reputation: 4 825

0

Ruby -n, 23 bytes

p IO.read($_)[4].ord*32

Try it online!

Linux ELF version. TIO link tests the interpreter on itself.

Kirill L.

Posted 2018-04-12T22:55:44.713

Reputation: 6 693

0

Bash, 36 bytes

cp $1 x
file x|egrep -o '32|64'|uniq

Try 64 bits online!

Try 32 bits online!

Pavel

Posted 2018-04-12T22:55:44.713

Reputation: 8 585

This may break if the executable's name contains the number 32 or 64. Try it online!

– Dennis – 2018-04-13T15:37:15.160

@dennis fixed it – Pavel – 2018-04-13T15:41:26.273

It would be much shorter to just read the ELF from STDIN. – Dennis – 2018-04-13T15:42:59.667