Konwertuj wyjście xxd na kod powłoki

15

Ręczne pobieranie danych wyjściowych z xxd i przekształcanie ich w użyteczny kod powłoki nie jest przyjemnością, więc Twoim zadaniem jest zautomatyzowanie tego procesu.

Zasady

Twoje zgłoszenie może być funkcją, lambda, skryptem lub jakimkolwiek rozsądnym odpowiednikiem. Możesz wydrukować wynik lub jeśli przesłana funkcja jest funkcją / lambda, możesz ją również zwrócić.

Ci program musi wziąć trzy argumenty, z których pierwszym jest łańcuch zawierający wyjście xxd, prowadził bez argumentów innych niż nazwy pliku, na przykład: xxd some_file. Oto przykład, jak będzie wyglądał pierwszy argument:

00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY

Musisz wziąć środkową sekcję zawierającą bajty (pierwsze 8 kolumn po :) i przekształcić ją w kod powłoki, usuwając wszelkie białe znaki, a następnie umieszczając \xprzed każdym bajtem.

Oto, jakie powinny być dane wyjściowe dla powyższego wejścia (ignorując inne argumenty):

\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e\x58\x58\x58\x58\x59\x59\x59\x59

Możesz założyć, że pierwszy argument zawsze będzie prawidłowym wyjściem xxd, uruchamianym bez argumentów innych niż nazwa pliku.

Twój wynik powinien być również ciągiem, w którym odwrotne ukośniki są dosłowne, a nie jako znaki specjalne. Kiedy mówię „\ x65”, nie mówię o bajcie 0x65, ani nawet o literze „A”. W kodzie będzie to ciąg „\ x65”.

Drugi argument określa, gdzie na wyjściu xxd powinien się rozpocząć kod powłoki, a trzeci określa, gdzie powinien się kończyć. Jeśli trzeci argument to -1, zakończy się na końcu wyjścia xxd. Drugi i trzeci argument również zawsze będą nieujemne, z wyjątkiem sytuacji, gdy trzeci jest-1

Oto kilka przypadków testowych:

Argument 1:

00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY

Argument 2 7:, Argument 3: e(oba są łańcuchami reprezentującymi liczby szesnastkowe)

Wynik: \xc9\xcd\x80\xeb\x16\x5b\x31\xc0

Argument 1:

00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY

Argument 2 0:, Argument 3:2e

Wynik: \x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e

Argument 1:

00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY

Argument 2 a:, Argument 3:-1

Wynik: \xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e\x58\x58\x58\x58\x59\x59\x59\x59

Wygrywa kod z najmniejszą liczbą bajtów. Zwycięzca zostanie ogłoszony za siedem dni, 15 sierpnia 2016 r. (Ale późniejsze zgłoszenia są nadal mile widziane).

Aktualizacja

Gratulacje dla @Adnan za zwycięstwo!

addison
źródło
Aby wyjaśnić, czy wpisy mogą zwracać ciąg znaków, czy muszą go wydrukować?
Jordan
Zwracanie łańcucha jest w porządku, o ile jest to funkcja, lambda lub coś w tym stylu (zaktualizowałem reguły, aby określić to po zapytaniu).
addison
1
Czy możemy również zwrócić zwykłe kody ASCII, gdy kod można wydrukować? Np. ~Zamiast \x7e. Czy możemy wrócić \tzamiast \x09?
orlp
@orlp Niestety nie, musi być w spójnym formacie.
addison,
Czy argumenty muszą być szesnastkowe? Ponadto sposób, w jaki podałeś drugi przykład, 7wygląda na indeks zerowy i ejest indeksem opartym na jednym ( e-7=7ale w twoich wynikach jest 8 kodów szesnastkowych), czy coś przeoczyłem?
Neil,

Odpowiedzi:

5

05AB1E , 39 38 bajtów

Dane wejściowe w formularzu:

arg2
arg3
arg1

Kod:

²\|vy9F¦}40£ðK}J2ô„\xì²H>²®Qi²}£¹HF¦}J

Wyjaśnienie:

²\                                       # Get the first two inputs and discard them.
  |                                      # Take the rest of the input as an array.
   vy         }                          # For each line...
     9F¦}                                #   Ten times, remove the first character.
         40£                             #   Only remain the substring [0:40].
            ðK                           #   Remove spaces.
               J                         # Join the string.
                2ô                       # Split into pieces of 2.
                  „\xì                   # Prepend a "\x" at each string.
                      ²H                 # Convert the second line from hex to int.
                        >                # Increment by one.
                         ²               # Push the second input again.
                          ®Qi }          # If equal to -1...
                             ²           #   Push the second input again.
                               £         # Take the substring [0:(² + 1)].
                                ¹H       # Convert the first input from hex to int.
                                  F¦}    # Remove that many characters at the beginning.
                                     J   # Join the array and implicitly output.

Wykorzystuje kodowanie CP-1252 . Wypróbuj online! .

Adnan
źródło
12

Bash + coreutils + xxd, 73 71 69 bajtów

printf \\x%s `xxd -r|xxd -p -s0x$1 -l$[(e=1+0x$2)?e-0x$1:-1]|fold -2`

Oczekuje zrzutu heksowego na STDIN i start / end jako argumenty wiersza poleceń.

Spowoduje to wydrukowanie niektórych ostrzeżeń do STDERR, co jest domyślnie dozwolone.

Dennis
źródło
1
Miałem nadzieję, że ktoś faktycznie skorzysta xxdz ich rozwiązania!
Addison,
@Addison Próbowałem, ale mój język nie obsługuje znaków nowego wiersza w wierszu poleceń. : c
Addison Crump
Jestem w stanie wymienić 16#z 0x?
Cyfrowa trauma
@DigitalTrauma Myślałem, że to xxdcoś, ale wydaje się, że działa wszędzie.
Dennis,
1
Tak, bash analizuje fabrycznie numery 0xnstylów szesnastkowych i 0mósemkowych: gnu.org/software/bash/manual/bash.html#Shell-Arithmetic . echo $[0x2a] $[052].
Cyfrowa trauma
5

JavaScript, 84 bajty

(s,f,t,u)=>s.replace(/.*:|  .*\n?| /g,'').replace(/../g,'\\x$&').slice(f*4,++t*4||u)

Objaśnienie: Usuwa wszystkie niechciane części zrzutu, dołącza \xdo każdej pary heksów, a następnie wyodrębnia pożądaną część wyniku. ||usłuży do konwersji zera uzyskanego przez zwiększenie -1parametru, na undefinedktóry jest magiczna wartość, która powoduje slicewycięcie do końca łańcucha. 101 bajtów, jeśli fi tsą ciągami cyfr szesnastkowych:

(s,f,t,u)=>s.replace(/.*:|  .*\n?| /g,``).replace(/../g,`\\x$&`).slice(`0x${f}`*4,t<0?u:`0x${t}`*4+4)
Neil
źródło
Zamiast tego (s,f,t,u)=>możesz zrobić s=>f=>t=>u=>, aby zaoszczędzić kilka bajtów.
Ismael Miguel,
@ IsmaelMiguel Przepraszamy, to działa tylko dla funkcji z dokładnie dwoma faktycznymi parametrami. W moim konkretnym przypadku umusi to być dodatkowy parametr i nie można go curry.
Neil,
@ IsmaelMiguel Też tak naprawdę dłużej ...
Jakob
5

Rubinowy: 90 89 87 79 63 bajtów

-2 bajty dzięki @addison
-8 bajtów dzięki @PiersMainwaring

->s,x,y{'\x'+s.scan(/(?<=.{9})\w\w(?=.* )/)[x.hex..y.hex]*'\x'}

Zobacz testy na repl.it: https://repl.it/Cknc/5

Jordania
źródło
Można wymienić .joinze *""aby zaoszczędzić 2 bajtów.
addison,
Można wymienić .map{|h|h.to_i(16)}z .map(&:hex)zaoszczędzić 8 więcej bajtów!
piersadrian
Dzięki @PiersMainwaring! Głupie z mojej strony, żeby o tym zapomnieć. Właściwie to uratowało mnie 16, ponieważ okazało się, że krótsze jest samodzielne wzywanie .hexargumentów!
Jordania
4

Galaretka , 48 44 bajtów

ØhiЀɠ’ḅ¥®L’¤Ạ?⁴‘
ṣ⁷ṫ€⁵ḣ€40Fḟ⁶s©2ḣ¢ṫ¢[“\x”]p

Oczekuje to, że zrzut heksadecymalny jest jedynym argumentem wiersza poleceń, a punkty końcowe i początkowe na STDIN, w tej kolejności, oddzielone linią.

Wypróbuj online!

Dennis
źródło
Chciałbym zobaczyć wyjaśnienie tego;)
Conor O'Brien
Dodam później, ale najpierw spróbuję zagrać w golfa. 51 bajtów galaretki kontra 69 bajtów Basha nie może mieć racji ...
Dennis,
3

PowerShell v2 +, 175 157 142 133 129 bajtów

param($a,$b,$c)'\x'+(($z=$a-split"`n"|%{$_[10..48]-ne32-join''-split'(..)'-ne''})["0x$b"..(("0x$c",$z.count)[$c-eq-1])]-join'\x')

Staje wejściowego $a, $b, $cz $aalbo jako znak nowego oddzielone łańcucha, lub PowerShell `npostaci oddzielającej linii. Ustawiamy ciąg pomocnika$z jako mocno przetworzony $aw następujący sposób -

Najpierw -splitna nowych liniach, następnie dla każdej linii |%{...}przecinamy środkową sekcję [10..48], używamy -ne32do usuwania spacji, -jointo z powrotem w jeden długi ciąg, -splitto na co dwa znaki (zachowując dwa znaki), i-ne'' do usuwania pustych elementów. Powoduje to tablicę dwuelementowych ciągów, takich jak ('31','c0','b0'...).

Następnie kroimy na tę tablicę na podstawie $brzutowania za pomocą operatora szesnastkowego do wartości $c. Musimy tutaj użyć pseudo-trójki, która wyjaśnia, czy $cjest, -1czy nie. Jeśli tak, wybieramy .count(tzn. Element końcowy) z $z. W przeciwnym razie po prostu dodamy 0xoperator szesnastkowy za $cpomocą łańcucha. Zauważ, że jest to indeksowane zero.

W tym wycinku tablicy elementy są -joinedytowane razem z literałem, \xtworząc jeden ciąg. Jest to poprzedzone kolejnym dosłownym tekstem, \xa wynik pozostaje w przygotowaniu. Drukowanie jest niejawne.

Przykład

PS C:\Tools\Scripts\golfing> .\xxd-output.ps1 "00000000: 31c0 b046 31db 31c9 cd80 eb16 5b31 c088  1..F1.1.....[1..
00000010: 4307 895b 0889 430c b00b 8d4b 088d 530c  C..[..C....K..S.
00000020: cd80 e8e5 ffff ff2f 6269 6e2f 7368 4e58  ......./bin/shNX
00000030: 5858 5859 5959 59                        XXXYYYY" a -1
\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e\x58\x58\x58\x58\x59\x59\x59\x59
AdmBorkBork
źródło
Czy możesz uzyskać dostęp do powłoki za pomocą tego języka?
Addison Crump
@VTCAKAVSMoACE Teoretycznie, biorąc pod uwagę nowy Podsystem Windows dla Linuksa , powinno być możliwe łączenie elementów i / lub przekazywanie parametrów za pomocą wiersza poleceń. Wdrożenie pozostawiono czytelnikowi jako ćwiczenie. ;-)
AdmBorkBork
2

Galaretka , 39 38 37 bajtów

ØhiⱮɠ’ḅ¥ȷ9Ṃ?⁴‘
Ỵṫ€⁵ḣ€40Fḟ⁶s2ṭ€⁾\xḣ¢ṫ¢

Wypróbuj online!

Teraz bije 05AB1E! (pomimo braku wbudowanego „konwertuj z szesnastkowego”)

Taki sam format wejściowy jak rozwiązanie Dennisa .

Użyj , która jest nową funkcją (skrót od Ѐ). Bez niego zajęłoby to 38 bajtów.

użytkownik202729
źródło
Działa tylko dla danych wejściowych z długością do 1e9.
user202729,
Ale jeśli jest na FAT32 (gdzie wielkość wejściowa wynosi co najwyżej 2 GB), wystarczy.
user202729,
1

Perl, 114 bajtów

($_,$a,$b)=@ARGV;s/^.*:|\S*$|\s//gm;@_=(m/../g);for(@_){s/^/\\x/}$"='';say substr"@_",4*$a,$b!=-1?4*($a+$b):2<<20;

Argumenty podane w wierszu poleceń jako cytowany ciąg, po którym następują dwie liczby. Liczby są pobierane w systemie dziesiętnym (wiem, że w przykładach użyto hexa, ale nie podano go w poście)

Technicznie działa tylko na danych wejściowych o wielkości do 2 ^ 21 bajtów, ponieważ metoda podłańcuchowa perla jest głupia

theLambGoat
źródło
Najwyraźniej zakres jest inclusive, więc na przykład 7do epowinno skutkować ciąg o długości 32
Neil
1

Python, 140 bajtów

lambda O,a,b:''.join(sum([['\\x'+x[:2],('','\\x')[len(x)>2]+x[2:]]for x in O.split()if len(x)<5],[])[int(a,16):(int(b,16)+1,None)[b=='-1']])

https://repl.it/ClB3

Dzieli oryginalny ciąg i zrzuca elementy, jeśli mają mniej niż pięć znaków, poprzedza \xi kroi według drugiego i trzeciego argumentu.

Wersja 162-bajtowa, jeśli musimy obsługiwać inne typy danych wyjściowych nieokreślone przez pytanie:

import re
J=''.join
def f(x,a,b):r=J(J(re.findall(':(.*?)  ',x)).split());print J(['\\x'+i+j for i,j in zip(r,r[1:])][::2][int(a,16):(int(b,16)+1,None)[b=='-1']])
atlasolog
źródło
To nie zadziała, jeśli np. Ostatnia linia jest podobna, 00000030: 5858 58 XXXponieważ wyciągnie ostatnią porcję i otrzymasz coś takiego \x58\x58\x58\xXX\xX.
AdmBorkBork,
@ TimmyD Nie sądziłem, że ta sprawa musi zostać załatwiona, co nie jest zgodne ze specyfikacją wyzwania.
atlasolog
Odczytałem wyzwanie, ponieważ podany pierwszy argument jest tylko przykładem, więc xxdzamiast tego można użyć innego wyjścia. „Oto przykład, jak będzie wyglądał pierwszy argument:”
AdmBorkBork
0

Python 2 i 3 - 164 162 150 146 134 150 bajtów

Teraz akceptuje ciągi szesnastkowe dla drugiego i trzeciego argumentu.

j=''.join
def f(a,b,c):s=j(x[10:49].replace(' ','')for x in a.split('\n'));print(j('\\x'+s[i:i+2]for i in range(int(b,16)*2,1+2*int(c,16)%len(s),2))
sufitowy
źródło
0

Python 3.5, 125 bajtów

import re
lambda s,b,e:re.sub(r'(\w\w)',r'\\x\1',re.sub(r'^.*?:|  .*$|\s','',s,0,8)[2*int(b,16):[2*int(e,16)+2,None][e<'0']])

Nie golfowany:

def f(s,b,e):
    b = 2*int(b,16)
    e = [2*int(e,16)+2,None][e<'0']
    x = re.sub(r'''(?v)   # verbose (not in golfed version)
            ^.*?:     # match begining of line to the ':'
           |  .*$     # or match '  ' to end of line
           |\s        # or match whitespace
           ''',
           '',        # replacement
           s,
           0,         # replace all matches 
           re.M       # multiline mode
           )
    y = re.sub(r'(\w\w)', # match pairs of 'word' characters
           r'\\x\1',  # insert \x
            x[b:e])
    return y
RootTwo
źródło