Big oder Little Endian

57

Schreiben Sie ein Programm oder eine Funktion, die eine Lif-Ausführung auf einer Little-Endian-Architektur oder eine Bif-Ausführung auf einer Big-Endian-Architektur ausgibt . Die Ausgabe in Kleinbuchstaben loder bist ebenfalls akzeptabel.

Es erfolgt keine Eingabe.

Das Scoring ist Codegolf, also gewinnt der Code mit den wenigsten Bytes.

Bearbeiten: Gemäß den Kommentaren unten stelle ich klar, dass der Eintrag auf beiden Architekturen ausgeführt werden kann.

Ich glaube, dass es nur eine Antwort gibt, die davon betroffen ist, und diese Antwort hat deutlich gezeigt, dass dies der Fall ist.

Liam
quelle
1
Die Erinnerung an die Box. Ich bin mir nicht sicher, was du meinst
Liam
7
Ich denke, das ist eine interessante Herausforderung (und es liegt außerhalb der Norm), aber es wird extrem schwierig sein, sie zu testen. Zumal der Großteil des Codes extrem plattformspezifisch sein wird.
DJMcMayhem
7
Ja, ich denke, es wird interessant sein, denn es ist hoffentlich etwas, mit dem Esolangs und Golfsprachen schwerer zu tun haben als mit "normalen" Sprachen. Ich habe das Gefühl, dass sie nicht so schwer zu überprüfen sein werden. Im schlimmsten Fall sollten sie von Hand überprüfbar sein
Liam
2
Ich denke, eine Antwort basierend auf einem bestimmten Maschinencode ist verboten? Andernfalls wäre B0 4C C3das mov al, 'L' / retoder unsigned char f(){ return 'L'; }eine gültige x86-Antwort.
Margaret Bloom
5
Bravo! für eine Code-Golf-Herausforderung, bei der universelle Programmiersprachen wettbewerbsfähig sein können.
PellMell

Antworten:

42

Python, 33 Bytes

import sys
exit(sys.byteorder[0])

sys.byteorderist entweder 'little'oder 'big'(und für diejenigen unter Ihnen, die diesen Satz lesen, ohne auf den Code zu achten, [0]bedeutet das, das erste Zeichen zu nehmen).

Anders Kaseorg
quelle
Die Herausforderung besagt, dass die Ausgabe Lund B(oder die Kleinbuchstabenvariante) nicht das gesamte Wort sein muss.
user2428118
43
Deshalb heißt es sys.byteorder[0], dh der erste Char von byteorder.
S3LPH
36

C 26 Bytes

a=66<<24|76;f(){puts(&a);}

Nimmt 32-Bit- intund ASCII-Zeichen an. Getestet auf amd64 (Little-Endian) und mips (Big-Endian).

GCC, 23 Bytes

00000000: 613d 2742 0000 4c27 3b66 2829 7b70 7574  a='B..L';f(){put
00000010: 7328 2661 293b 7d                        s(&a);}

Vorgeschlagen von feersum. Der Wert von Konstanten mit mehreren Zeichen ist implementierungsabhängig, dies scheint jedoch in GCC zu funktionieren. Auf den gleichen Architekturen getestet.

Anders Kaseorg
quelle
7
Kürzere ist a='B\0\0L';Das \0s kann durch null Bytes ersetzt werden.
Feersum
1
@feersum Die Endlichkeit von Konstanten mit mehreren Zeichen scheint von der Implementierung abhängig zu sein. Normalerweise würde ich mir beim Codegolf nicht so viele Sorgen machen, aber bei dieser Herausforderung geht es darum, zwischen Implementierungen zu unterscheiden.
Anders Kaseorg
Funktioniert dieser Code derzeit nicht in GCC?
Feersum
1
@feersum C89 erlaubt beides.
Anders Kaseorg
1
Unter Verwendung von xlc (VisualAge C ++ Professional / C für AIX Compiler, Version 6) auf einem RS6000 mit AIX 5.2 druckt das 26-Byte-Programm erfolgreich "B"
Jerry Jeremiah,
24

MATLAB / Octave, 24 Bytes

[~,~,e]=computer;disp(e)

Die computerFunktion gibt Auskunft über den Computer, auf dem sie läuft. Die dritte Ausgabe ist Endianness: Loder Bfür Little- bzw. Big-Endian.

Probieren Sie es auf Ideone .

Luis Mendo
quelle
1
Was. Dies ist etwas für Stackoverflow, das wusste ich nicht!
Brain Guider
20

JavaScript ES6, 50 Byte

_=>"BL"[new Int8Array(Int16Array.of(1).buffer)[0]]

Ich weiß nicht, wer entschieden hat, dass es für TypedArray- Objekte eine gute Idee ist , die native Endianness des Interpreters aufzudecken, aber hier sind wir.

Anders Kaseorg
quelle
5
WebGL-Leute hielten es für eine gute Idee, Endianness bei der Übergabe an die GPU nicht konvertieren zu müssen. So ziemlich jeder andere fand es dumm ... :(
gsnedders
11

C, 36 35 Bytes

1 Byte danke an @algmyr und @owacoder.

main(a){printf(*(char*)&a?"L":"B");}
main(a){putchar(66+10**(char*)&a);}
main(a){putchar("BL"[*(char*)&a]);}

Credits hier .

Ungetestet, da ich keine Big-Endian-Maschine habe.

Undichte Nonne
quelle
2
Lässt die C-Spezifikation eine mainFunktion mit einem Argument zu ?
CodesInChaos
@codesinchaos ja das tut es. Dies ist die Anzahl der angegebenen Befehlszeilenargumente. Normalerweise wird hier eine Variable initiiert, 1weil keine Eingabe erfolgt (und der Programmname gilt immer als erstes Argument)
Liam
2
@Liam: Wenn etwas anderes als 0 oder 2 zulässig ist, wird die Implementierung in C11 definiert.
1
Oder main(a){putchar("BL"[*(char*)&a]);}.
Owacoder
2
Wenn Sie Schlamassel mit der Aufrufkonvention geht es hinunter bis 31: main(char a){putchar("BL"[a]);}.
Andrea Biondo
8

Mathematica, 22

{B,L}[[$ByteOrdering]]

Dies verstößt wahrscheinlich gegen eine Regel, die besagt, dass keine eingebaute Funktion verwendet wird, aber ich bin nicht wirklich daran interessiert, eine Alternative für das Rube Goldberging zu finden.

Mr.Wizard
quelle
1
Built-Ins sind in Ordnung (die meisten Antworten verwenden sie auch)
Liam
2
Und wieder einmal hat Mathematica eine eingebaute!
Gcampbell
3
Ich denke, dies ist ein Ausschnitt, kein Programm oder eine Funktion, und Sie sollten hinzufügen &, um es zu einer Funktion zu machen. (Es kann jedoch zu Meinungsverschiedenheiten kommen, was ein „Programm“ ausmacht.)
Anders Kaseorg,
1
@Anders Ich bin nicht wirklich vertraut mit den aktuellen Standards für PCG (wenn ich jemals war) , aber meiner Meinung nach einem Vorteil einer interpretierten Sprache ist , dass ein Ausschnitt ist ein Programm. Dies kann wie jedes andere Programm in Mathematica eigenständig ausgeführt werden .
Mr.Wizard
1
@ Mr.Wizard Beachten Sie, dass sich ein "Programm" in Mathematica auf ein eigenständiges Skript bezieht (das explizites Drucken erfordert), während in dieser Antwort die REPL verwendet wird.
LegionMammal978
8

C 27

Ein Byte länger, aber hier ist es trotzdem:

f(){putchar(htons(19522));}
Digitales Trauma
quelle
Es hat gut funktioniert, können Sie es mir bitte erklären.
ABcDexter
3
@ABcDexter ist die binäre Erweiterung von 19522 1001100 01000010(Leerzeichen, um Bytes zu trennen). Wenn Sie nun jedes Byte nehmen, zurück zur Basis 10 konvertieren und die ASCII-Tabelle überprüfen, werden Sie sehen, dass diese Byte-Sequenz äquivalent zu ist LB. htonswird nicht sein Ding , und putcharwird das LSB nur drucken. In Big-Endian-Systemen hat das Bin Little-Endian htonsdie Bytes gekippt, so wie es das LSB ist L.
Kroltan
Ersetzen Sie 19522durch 'LB'für Compiler-Warnungen und -1 Byte.
Stan Strum
8

PowerPC-Maschinencode - 20 Byte

PowerPC ist Bi-Endian (die Endian-Funktion kann beim Start eingerichtet werden), daher sollte dieser Code der Anforderung entsprechen, sowohl auf BE- als auch auf LE-Computern ausgeführt werden zu können. Dies ist eine Funktion, die 1 zurückgibt'L' oder 'B'von der aktuell eingestellten Endianzahl abhängt.

Als Funktion entspricht AFAICT dem SVR4 PowerPC ABI (von Linux auf ppc32 verwendet), dem PowerOpen ABI (von AIX verwendet) und dem OS X ABI. Insbesondere beruht es nur auf der Tatsache, dass GPR 0 ein flüchtiges Scratch-Register ist und GPR 3 verwendet wird, um "kleine" Werte zurückzugeben.

00000000 <get_endian>:
   0:   7c 00 00 a6     mfmsr   r0
   4:   54 03 0f fe     rlwinm  r3,r0,1,31,31
   8:   1c 63 00 0a     mulli   r3,r3,10
   c:   38 63 00 42     addi    r3,r3,66
  10:   4e 80 00 20     blr

Nun geht es so:

  • das MSR wird in das GP-Register 0 eingelesen; das MSR enthält bei Bit 31 die Endian-Einstellungen (0 = Big Endian; 1 = Little Endian);
  • rlwinmExtrakte nur das Bit: es den Wert in GPR0 nimmt, r Otates l inks um 1 Stelle (so dass nun in der Position 0) und m fragt es mit 1 (der Maske durch jene 31,31 erzeugten 2 ); das Ergebnis wird in das GP-Register 3 eingetragen;
  • multiplizieren Sie das Ergebnis mit 10 und addieren Sie 66 ( 'B') (10 ist die Differenz zwischen 'L'und 'B')
  • Kehren Sie schließlich zum Anrufer zurück

Anmerkungen

  1. Ja, die Frage lautet, ob gedruckt werden soll , aber es ist nicht klar, wie ich in Assemblys drucken soll, die auf verschiedenen Betriebssystemen unverändert ausgeführt werden sollen. =)
  2. für interessierte siehe die rlwinm- dokumentation; Da ich so gut wie nichts über PowerPC wusste, fand ich diese Art von Anweisungen äußerst interessant.

    Update 2018 : Raymond Chen veröffentlicht eine Reihe über die PowerPC-Architektur. Sie finden hier seinen großartigen Beitrag über rlwinm& friends.

Matteo Italia
quelle
7

Java 8, 96, 64, 52 Bytes

()->(""+java.nio.ByteOrder.nativeOrder()).charAt(0);

Ein Golf basierend auf dieser SO Antwort . Das gesamte Guthaben geht an @LeakyNun und @AlanTuning. Java behält die Pechsträhne.

96 Bytes:

 char e(){return java.nio.ByteOrder.nativeOrder().equals(java.nio.ByteOrder.BIG_ENDIAN)?'b':'l';}

64 Bytes:

char e(){return(""+java.nio.ByteOrder.nativeOrder()).charAt(0);}

Ungetestetes B / C Ich habe keinen Zugriff auf eine Big-Endian-Maschine.

Blau
quelle
1
char e(){return(""+java.nio.ByteOrder.nativeOrder()).charAt(0);}
Undichte Nonne
char e(){return(""+java.nio.Bits.byteOrder()).charAt(0);}
Undichte Nonne
@LeakyNun Ich sehe keine Bits in der Java-API, und wenn ich sie starte, erhalte ich die Meldung "Bits sind in java.nio nicht öffentlich"
Blau
Oh, dann gut.
Undichte Nonne
52 Bytes, wenn Sie ein Lambda verwenden! ()->(""+java.nio.ByteOrder.nativeOrder()).charAt(0);
Shaun Wild
6

Perl, 38 36 Bytes

say+(pack"L",1 eq pack"V",1)?"L":"B"

Packt eine Zahl in der Standard-Bytereihenfolge des Systems und vergleicht sie mit einer Zahl in Little-Endian-Bytereihenfolge.

ein Spaghetto
quelle
6

(G) Viertens 24 Bytes

here $4200004C , c@ emit

Geht davon aus, dass die Zellen 32 Bits sind (und dass Ihr Forth - Interpreter unterstützt gforth der Basis Präfixe ). Es speichert einfach die Nummer 0x4200004C im Speicher und zeigt dann das Byte am unteren Ende an.

Jwodder
quelle
5

C 34 Bytes

Dies setzt eine ASCII-Zeichencodierung voraus

main(a){putchar(66+10**(char*)a);}

Rufen Sie ohne Argument an.

Erläuterung:

Auf Abruf awird 1. *(char*)aauf das erste Byte von zugegriffena , auf Little-Endian-Plattformen 1, auf Big-Endian-Plattformen 0.

Auf Big-Endian-Plattformen wird dieser Code daher 66 + 10 * 0 = 66 an übergeben putchar. 66 ist der ASCII-Code für B. Auf Little-Endian-Plattformen wird 66 + 10 * 1 = 76 übergeben. Dies ist der ASCII-Code für L.

Celtschk
quelle
5

C #, 60 52 Bytes

C # ist in dieser Hinsicht überraschend wettbewerbsfähig.

char e=>System.BitConverter.IsLittleEndian?'L':'B';

Dank an Groo für die C # 6-Syntax.

60 Bytes:

char e(){return System.BitConverter.IsLittleEndian?'L':'B';}
BgrWorker
quelle
Mit der C # 6-Syntax können Sie sie ein wenig verkürzen: char e=>System.BitConverter.IsLittleEndian?'L':'B';Natürlich wird der Wert durch diese (sowie die Java-Antwort) nicht gedruckt.
Groo
Willkommen bei Programming Puzzles & Code Golf! Dies ist eine schöne erste Antwort.
Alex A.
5

Julia, 24 19 Bytes

()->ntoh(5)>>55+'B'

Dies ist eine anonyme Funktion, die keine Eingabe annimmt und a zurückgibt Char. Um es aufzurufen, weisen Sie es einer Variablen zu. Es wird davon ausgegangen, dass Ganzzahlen 64-Bit sind.

Die ntohFunktion konvertiert die Endianzahl des an sie übergebenen Werts von der Netzwerk-Byte-Reihenfolge (Big Endian) in die vom Host-Computer verwendete. Auf Big-Endian-Rechnern ntohist die Identitätsfunktion, da keine Konvertierung durchgeführt werden muss. Auf Little-Endian-Rechnern werden die Bytes also getauscht ntoh(5) == 360287970189639680. Was vielleicht auch lesbarer ist gleich:0000010100000000000000000000000000000000000000000000000000000000 in binär.

Wenn wir das Ergebnis ntoh(5)um 55 nach rechts verschieben , erhalten wir 0 auf Big-Endian-Maschinen und 10 auf Little-Endian-Maschinen. Wenn 'B'wir das zur Zeichenkonstante hinzufügen , erhalten wir 'B'bzw. 'L'für Big- oder Little-Endian-Maschinen.

5 Bytes gespart dank FryAmTheEggman und Dennis!

Alex A.
quelle
Für 32-Bit müsste man 55 auf 23 ändern (auch die 5 in 16-Bit hätte 7 sein sollen, mein Fehler). Ich denke Dennis meinte so etwas wie ()->ntoh(5)>>55+'B':?
FryAmTheEggman
1
f()='L'-ntoh(10)%16und f()='L'-ntoh(10)&10sollte auf allen Plattformen funktionieren.
Dennis
5

PHP 5.6, 41 31 Bytes (Danke an isertusernamehere)

<?=unpack(S,"\x01\x00")[1]-1?B:L;

PHP 7, 41 Bytes

echo unpack('S',"\x01\x00")[1]-1?'B':'L';

Die Idee wurde gestohlen von: https://stackoverflow.com/a/24785578/2496717

Pinoniq
quelle
Sie können sparen 10 Bytes : <?=unpack(S,"\x01\x00")[1]-1?B:L;.
Insertusernamehere
5

Common Lisp, 27 Bytes

Getestet auf SBCL und ECL. Für einen portablen Ansatz sollte man Trivial-Features verwenden .

(lambda()'L #+big-endian'B)

Die #+Notation ist eine Lesezeitbedingung , die das nächste Formular nur dann liest, wenn der bedingte Ausdruck als wahr ausgewertet wird. Hier ist die Bedingung der gesamte #+big-endianText, was bedeutet, dass der Test erfüllt ist, wenn das :big-endianSchlüsselwort zur *FEATURES*Liste gehört (eine Liste, die unter anderem plattformspezifische Informationen enthält). Der folgende Ausdruck wird 'Bje nach Testergebnis entweder gelesen oder übersprungen. Wenn Ihre Plattform Big-Endian ist und Sie das obige Formular in die REPL schreiben, ist es genau so, als hätten Sie Folgendes geschrieben:

CL-USER>(lambda()'L 'B)

(Anm. CL-USER>Ist die Eingabeaufforderung)

Der Körper einer Funktion ist implizit PROGN, was bedeutet, dass nur die Auswertung des letzten Ausdrucks zurückgegeben wird. Also die oben gibt tatsächlich Symbol B. Wenn die Lesezeitbedingung jedoch false ergibt, lautet das Formular so, als ob Sie Folgendes geschrieben hätten:

CL-USER>(lambda()'L)

... was einfach das Symbol zurückgibt L.

Core-Dump
quelle
Snippets sind nicht erlaubt. schreiben Sie stattdessen vollständige Programme oder Funktionen.
Erik der Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Aktualisiert, danke
coredump
Hinweis: Snippets sind nur zulässig, wenn dies vom OP ausdrücklich gestattet wird.
Erik der Outgolfer
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ Könnten Sie einen Hinweis dazu geben? Es gibt andere REPL-Antworten hier und / oder Shell-Snippets und dieser Meta-Post würde vorschlagen, dass REPL-Antworten standardmäßig in Ordnung sein könnten. Vielen Dank.
Coredump
5

ARMv6 und höher: 20 Byte Maschinencode

0xE10F1000 : MRS   r0,CPSR        ; read current status register
0xE3110C02 : TST   r0,#1<<9       ; set Z flag if bit 9 set
0x03A0004C : MOVEQ r0,#'L'        ; return 'L' if Z clear
0x13A00042 : MOVNE r0,#'B'        ; return 'B' if Z set
0xEBxxxxxx : BL    putchar        ; print it (relative branch)

Ungetestet, da ich keine passende Maschine zur Hand habe. Bit 9 des CPSR gibt die aktuelle Lade- / Speicherendzeit an.

user1908704
quelle
Sie können eine Rückgabe von der Funktion verwenden ( BX lroder?) putchar, Da dies r0das richtige Register für das zurückgegebene Ergebnis ist.
Anatolyg
In der Tat war das (eigentlich MOV pc, lr) in einer meiner vorherigen Änderungen. Dies erfüllt jedoch die Spezifikation, den Brief zu drucken und nicht nur zurückzugeben.
user1908704
Möglicherweise lese ich die Referenz falsch, aber ich denke, dies kann in der "thumb 2" -Befehlscodierung erfolgen. Dies würde bedeuten, dass der erste Befehl 32 Bit lang bleibt ("Kodierung T1" auf Seite F7-2720 des ARM v8-Referenzhandbuchs, wodurch er zu 0xF3EF_8000 wird). Die Sekunde ist ebenfalls 32 Bit (die Codierung des Operanden ist etwas bizarr, kann jedoch mit "i: imm3" auf 0010 und "imm8" auf 00000010 erfolgen, was eine Gesamtanweisung von 0xF010_2F02 ergibt). Vor dem dritten Befehl müssen wir "ITE EQ" (0xBF0C) einfügen, um die Bedingungen für die nächsten beiden MOV-Befehle zu steuern, die zu 0x204C und ...
Jules
... 0x2042 (spart insgesamt 2 Bytes). Dann ist der endgültige BL-Befehl etwas schwierig darzustellen, weil die Bits der Adresse, die wir nicht kennen, auf die Bits des Befehls verteilt sind, die wir kennen, aber es ist auch eine 32-Bit-Codierung, so dass das Ergebnis wäre insgesamt 18 Bytes sein (F3 EF 80 00 F0 10 2F 02 BF 0C 20 4C 20 42 F ?? ?? ??). Ich glaube, dies ändert die Architektur in ARMv8 und höher, obwohl es möglicherweise in ARMv7 (?) Funktioniert.
Jules
4

Perl 5, 21 + 1 = 22 Bytes

Laufen Sie mit perl -E.

say ord pack(S,1)?L:B

Getestet auf amd64 (Little-Endian) und mips (Big-Endian).

Anders Kaseorg
quelle
Ist das -EFlag für die Byteanzahl wirklich erforderlich? Sie können einfach sagen, dass Sie Perl 5.10 verwenden (da der sayBefehl in dieser Version verfügbar ist)
Paul Picard
1
@PaulPicard Ist aber use 5.10.0;viel mehr Bytes!
Anders Kaseorg
1
@PaulPicard Dein Punkt ist falsch. Perl 5.10 benötigt den -ESchalter oder die useAnweisung für say.
Anders Kaseorg
3
-Eist bei PPCG "kostenlos". Sie müssen nichts hinzufügen.
Ven
1
(jedoch -nund -pnicht)
Ven
4

R 28 23 Bytes

substr(.Platform$endian,1,1)

.Platform$endianGibt zurück, bigwenn es auf Big Endian und littleauf Little ausgeführt wird. Hier wird mit substrentweder boder der erste Buchstabe der Ausgabe zurückgegeben l.

Da endianes das einzige Objekt ist, das mit einem ein object enthaltenen Objekt beginnt, .Platformkönnen wir es durch teilweise Übereinstimmung mit dem folgenden 23-Byte-Code reduzieren:

substr(.Platform$e,1,1)
Plannapus
quelle
3

Clojure, 46 44 Bytes

#(nth(str(java.nio.ByteOrder/nativeOrder))0)

Dies ist eine Funktion, die das Java-Builtin verwendet, um die Endianness der Maschine zu ermitteln. Holen Sie sich dann die String-Darstellung davon, die entweder "LITTLE_ENDIAN"oder ist, "BIG_ENDIAN"und nehmen Sie das erste Zeichen des gewählten Strings und geben Sie das zurück.

2 Bytes gespart dank @ cliffroot gespart .

Meilen
quelle
Was ist Clojure wirklich, ist es Lisp oder Java?
Undichte Nonne
@LeakyNun Vielleicht ein praktisches LISP, das mit Java funktioniert? Es ist schwer zu sagen.
Meilen
#(nth(str(java.nio.ByteOrder/nativeOrder))0)ist 2 Bytes kürzer
Cliffroot
3

Rubin, 3130 Zeichen.

puts [1].pack("s")>"\01"??L:?B

Hmm, muss ein besserer Weg sein. Zählen Sie 5 Zeichen weniger, wenn das Zeichen nicht ausgegeben werden muss, da meines Erachtens andere Lösungen das Drucken unterlassen. dh entfernen Sie den Teil "Puts", wenn Sie nicht möchten, dass etwas gedruckt wird.

akostadinov
quelle
Wenn ich mich richtig erinnere, können Sie nach Ruby 1.9 ?Lund ?Banstelle von verwenden puts :L undputs "B"
Sherlock9
Ich denke puts [76,66].pack("s")[0] wird funktionieren.
Wayne Conrad
@ Sherlock9, danke, ein Char weniger. @WayneConrad, füge vielleicht deine Antwort hinzu, ich habe keine Big-Endian-Maschine zum Testen zur Hand, aber auf Little-Endian funktioniert es. Aber wie diese Veränderung nicht funktioniert: puts [76,66].pack("s>")[0]. Das bedeutet, dass es aus irgendeinem Grund, den ich nicht gut verstehe, möglich ist, nicht an Big Endian zu arbeiten. Aber dieser scheint zu funktionieren (abgeleitet von Ihrer Lösung) puts [19522].pack("s>")[0]. WDYT? Ich frage mich, ob ich einen Ort finden kann, an dem ich Big Endian bewerten kann.
Akostadinov
Leider fehlt mir auch eine Big-Endian-Maschine zum Testen.
Wayne Conrad
3

Bash (und andere Unix-Shells), 32 (33) Bytes

Erster und zweiter Versuch:

case `echo|od` in *5*)echo B;;*)echo L;;esac # portable
[[ `echo|od` =~ 5 ]]&&echo B||echo L         # non-portable

Dank Dennis, kürzere Version:

od<<<a|grep -q 5&&echo L||echo B  # non-portable
echo|od|grep -q 5&&echo B||echo L # portable

Das echoDienstprogramm gibt eine Newline mit Hex-Wert 0Aund keine andere Ausgabe aus. Für <<<aes ist 61 0A.

Das odDienstprogramm interpretiert die Eingabe standardmäßig als Zwei-Byte-Wörter, die bei ungerader Byteanzahl mit Nullen aufgefüllt und in Oktal umgewandelt werden. Dies führt dazu, dass die Ausgabe des Echos als interpretiert wird 0A 00, das in einen 005000Big-Endian oder einen 000012Little-Endian konvertiert wird . 61 0Awird 005141in Little-Endian und 060412in Big-Endian. Die vollständige Ausgabe von od enthält auch Adress- und Größendaten, die wir nicht verwenden 0können 1, oder 2für den Test.

Der Befehl ist genau definiert, um die Endianität des Systems aufzudecken. Aus dem Standard :

Die bei der Interpretation numerischer Werte verwendete Bytereihenfolge ist implementierungsdefiniert, muss jedoch der Reihenfolge entsprechen, in der eine Konstante des entsprechenden Typs im Speicher des Systems gespeichert ist.

Kompatibilitätshinweise

Ich bin mir nicht sicher, ob ich echo|odAnführungszeichen ohne Anführungszeichen einfügen sollcase ] auf allen Systemen unterstützt wird. Ich bin nicht sicher, ob alle Systeme Shell-Skripte ohne Zeilenumbruch unterstützen. Ich bin mir größtenteils sicher, aber nicht 100% des Verhaltens von od beim Hinzufügen des Füllbytes auf Big-Endian-Systemen. Bei Bedarf echo akann für die tragbaren Versionen verwendet werden. Alle Skripte funktionieren in bash, ksh und zsh, und die portablen Skripte funktionieren in dash.

Random832
quelle
Keine der Änderungen ist notwendig; Setzen Sie einfach eine Shell, in der es funktioniert, in die Sprachenkopfzeile ein und schon sind Sie fertig.
Dennis
1
@ Dennis Ich mag zu tun , diese Art von Analyse ... obwohl es mehr Spaß , wenn ich noch etwas Nicht-Standard finden , die eine kürzere Antwort in bash oder zsh als die anderen bekommt. Vielleicht werde ich sehen, was getan werden kann[[
Random832
1
An der Analyse ist nichts auszusetzen. Der letzte Absatz klang nur so, als ob Sie unsicher wären, ob eine Shell-spezifische Antwort gültig ist ... od<<<a|grep -q 5&&echo L||echo Bsollte in Bash und anderen funktionieren.
Dennis
Ich habe es in einer Big-Endian-VM getestet und wie erwartet echo|odgedruckt 0000000\n005000\n0000001.
Dennis
@ user17752 Da Endianness die Ausgabe von nicht beeinflusst od -a.
Random832
3

PHP, 16 Bytes

<?=pack(S,14)^B;

Dabei werden zwei Tricks verwendet, die in den beiden vorhandenen PHP-Antworten nicht verwendet werden:

  1. Der an pack () oder unpack () übergebene Wert kann ein beliebiger Wert sein, nicht nur 0 oder 1.
  2. Der bitweise XOR-Operator ( ^) arbeitet mit Zeichenfolgen, und das Ergebnis ist nur so lang wie die kürzere Zeichenfolge, sodass weder eine Zeichenfolgenindizierung noch ein ternärer Operator erforderlich sind.
PleaseStand
quelle
2

Knoten, 42 Bytes

n=>require('os').endianness()[0]

Pro: Es gibt eine eingebaute. Con: Eigenschaftsnamen sind sehr lang

Downgoat
quelle
2

PowerShell, 44 Byte

[char](66+10*[BitConverter]::IsLittleEndian)

Character 66 ist B, und 10 Zeichen später ist die Nummer 76, L. Ein Boolescher Wert von "true" wird, 1wenn er in eine Zahl umgewandelt wird. BitConverterist eine Standard .NET Klasse.

Ben N
quelle
1

Schläger, 35 28 Bytes

(if(system-big-endian?)'B'L)

'Boder 'Lsind. Lassen Sie mich wissen, wenn dies nicht spezifisch genug ist :)

Winny
quelle
1

PHP, 22 Bytes

<?=ord(pack(S,1))?L:B;
Anders Kaseorg
quelle
1

Haskell (bei Verwendung von numerischen GHC-Typen mit Größenbeschränkung), 75 Byte

import Unsafe.Coerce
import GHC.Int
f="BL"!!fromEnum(unsafeCoerce 1::Int8)

(Nicht auf einer Big-Endian-Architektur getestet, aber es scheint, als sollte es funktionieren!)

Jules
quelle
1

K, 15 Bytes

    ("bl")@*6h$-8!`
    ,"l"

Erläuterung;

    From right to left;
    -8!`       /serialises the back tick and returns (0x010000000a000000f500)
    6h$-8!`    /This casts the result to `int which is type 6h(could have used `int$-8!`) - the result is (1 0 0 0 10 0 0 0 245 0i)
    *6h$-8!`   /* means first, we take the first item which is 1. Since it will be either 1 or 0, we can use it to index (@) into the two element list on the left i.e. ("bl")1 returns "l" and ("bl")0 returns b
Chromozorz
quelle
1

Bash, 27 Bytes

iconv -tucs2<<<䉌|head -c1

( U + 424C ) ist in drei UTF-8-Bytes codiert:E4 89 8C .

Es wird angenommen, dass iconvdie Funktion von glibc verwendet wird und dass ein UTF-8-Gebietsschema verwendet wird.

PleaseStand
quelle