Zadanie polega na napisaniu kodu identyfikującego naciśnięcie klawisza na klawiaturze. Możesz założyć, że jednocześnie naciśnięty jest tylko jeden klawisz i że istnieje standardowy układ klawiatury w USA. To jest układ z @ nad 2.
Kod powinien wyświetlać unikalny identyfikator każdego naciśniętego klawisza. Obejmuje to PrtScn, Scroll Lock, Pause, lewy Shift, prawy Shift, lewy Ctrl, prawy Ctrl, Caps Lock, Tab, Enter, Enter na klawiaturze numerycznej, Num Lock, Insert, Ins na klawiaturze numerycznej, Backspace, Del, F1 ... F12, Esc, lewy klawisz Windows, prawy klawisz Windows, Alt, AltGr, klucz aplikacji (menu kontekstowe) i tak dalej.
Twój kod powinien dalej czekać na naciśnięcia klawiszy i wyświetlać swoją tożsamość, dopóki nie zostanie zabity. Powinien jednak wypisać identyfikator, gdy tylko klucz zostanie zwolniony. Nie powinien wykonywać żadnych innych działań z otrzymywanych naciśnięć klawiszy i nie powinien generować niczego poza unikalnym identyfikatorem.
W odpowiedzi pokaż, co kodujesz, dla następujących naciśnięć klawiszy: Tab, Pauza, Enter, Enter na klawiaturze numerycznej, lewy klawisz Windows, prawy klawisz Windows, Wstaw i Ins na klawiaturze numerycznej.
Jeśli masz bardzo inną klawiaturę, wyzwaniem jest nadal wydawanie innego identyfikatora dla każdego klawisza na klawiaturze.
Odpowiedzi:
kod maszynowy x86, plik wykonywalny DOS,
29* 28 bajtówJest to plik wykonywalny COM dla MS-DOS , wymaga sprzętu kompatybilnego z IBM PC .
W szczególności kontroler 8042 PS / 2 lub bardziej prawdopodobne jego emulacja przez SMM .
Krótko mówiąc, powinien działać od razu po wyjęciu z pudełka na każdym głównym komputerze.
Kod źródłowy to
Program podzieliłem na dwie części.
Pierwsza część dotyczy odczytu skancodów . Skancody to wartości liczbowe powiązane z każdym kluczem.
Pamiętaj, że są to kody sprzętowe, nie zależą one od systemu operacyjnego ani zestawu znaków. Są jak zakodowana para (kolumna, rząd) klucza.
Każdy klawisz ma skancode, nawet te niestandardowe dziwne klawisze funkcyjne, które można znaleźć na niektórych klawiaturach (np. Klawisz „open calc”).
Niektóre klucze mają wielobajtowe scancode, mają prefiksy zaprojektowane do dekodowalności strumienia, po prostu patrząc na sekwencję bajtów.
Tak więc każdy klucz otrzymuje swój unikalny identyfikator, nawet CTRL, SHIFT, WinKeys i tak dalej.
Przetwarzane są tylko „kody złamania”, wysyłane po zwolnieniu klucza, a „make kody” są ignorowane.
Formery mają ustawiony wyższy bit (bit 7 dla bajtu), więc łatwo je rozpoznać.
Druga część dotyczy drukowania bajtu.
Drukowanie jest zawsze długie w montażu, nie mamy żadnych wbudowanych funkcji.
Krótko mówiąc, a ponieważ trzeba było wpisać identyfikator klucza, zrezygnowałem z liczb dziesiętnych lub szesnastkowych na rzecz osobistego kodowania.
Bajt xy, gdzie x oznacza wyższą wartość, ay niższa jest drukowana jako dwa kolejne znaki c 0 i c 1 zdefiniowane jako:
c 0 = 0x21 + y
c 1 = 0x21 + x
Zauważ, że dolny skubek jest drukowany jako pierwszy (to oszczędzało mi wymiany).
Uzasadnieniem jest odwzorowanie każdej z 16 możliwych wartości skrawka na kolejne znaki ASCII z „!”.
Po prostu jest to liczba szesnastkowa, ale z
!"#$%&'()*+,-./01
jako cyfra (als) zamiast0123456789abcdef
Uruchomienie go w DOSBoxie i naciśnięcie losowego klawisza (z których część jest klawiszem specjalnym, ale należy pamiętać, że jako proces Windows DOSBox nie może przechwycić wszystkich kluczy) daje
Zauważ, że ten program nigdy się nie kończy (ponadto przejmuje pełną kontrolę nad komputerem poprzez wyłączenie przerwań), jak sądzę, że było to zamierzone przez pytanie (po prostu nie ma zabijania procesów w DOS).
* Zmniejszone podziękowania dla CodyGray .
źródło
IN
instrukcji okazało się mniejsze pod względem bajtów niż wywołanie przerwań ROM BIOS (np.int 16h
Funkcja 10h)?in
instrukcji. To naprawdę bardzo dobra uwaga. Jeśli jeszcze tego nie zrobiłeś, dlaczego nie opublikować go jako odpowiedzi? :)xchg
z akumulatorem jako jednym z rejestrów jest 1 bajt, więc to lepiej niż 2 bajtymov
.int 16h
polega na tym, że nie otrzymuję kodów skanowania dla klawiszy Shift, przewijania blokady lub pauzy / przerwy (być może innych), a to jest wymagane przez wyzwanie. Twoje rozwiązanie odczytu danych wejściowych bezpośrednio z I / O działa, chociaż wydaje mi się, że zwraca tę samą wartość dla wszystkich kluczy w klastrze Ins / Del / Home / End / PgUp / PgDown.Java 7 lub nowsza,
246228 bajtówNie golfowany:
-18 dzięki @ OlivierGrégoire do
show()
,0<0
iimport java.awt.event.*;
Co skutkuje w:
Nawet obsługuje naciśnięcia klawisza Shift dla wielkich liter, klawisza Windows, Caps Lock itp. Możesz zobaczyć, że drukuje również „modyfikatory”, które są „trzymanymi klawiszami”.
źródło
HTML (z Javascriptem),
4631 znaków,4631 bajtówUżywając tego do rozróżnienia wchodzenia i powrotu Numpada, LControl i RControl ...Już nie, ponieważ apsillery znaleźli sposób na zrobienie tego za pomocą wywołania funkcji signle.Określone wyniki:
WYJŚCIA, KTÓRE WCIĄŻ SĄ Z NUMERAMI, KTÓRE NIE MOGĘ TESTOWAĆ NA MOIM LAPTOPIE
PROSZĘ CZEKAĆ NA MNIE
PrtScn -> PrintScreen
Scroll Lock -> ScrollLock
Pause -> Pause
left Shift -> ShiftLeft
right Shift -> ShiftRight
left Ctrl -> ContrlLeft
right Ctrl -> ControlRight
Caps Lock -> CapsLock
Tab -> Tab
Enter -> Enter
Enter on the number pad -> NumpadEnter
Num Lock -> NumLock
Insert -> Insert
Ins na klawiaturze numerycznej -> Numpad0
Backspace -> Backspace
Del -> Usuń
F1 ... F12 -> F1 do F12
Esc -> Escape
lewy klawisz Windows -> MetaLeft
prawy Klawisz Windows -> MetaRight
Alt -> AltLeft
AltGr -> AltRight (rodzaj błędu, wykrywa ControlLeft, a następnie AltRight,ale tak naprawdę jest AltRight)
klawisz aplikacji (menu kontekstowe) -> Menu kontekstowe
EDYCJE:
1 bajt zapisany
;
po wywołaniu func18 bajtów zapisanych dzięki Lil 'Bits i produktom ETH, zauważyli, że zapomniałem skracać nazwy func i var.
32 bajty zaoszczędzone dzięki RogerSpielker, zauważył, że robię sparowany kod bez powodu; i ponownie -2 bajty:
onkeydown
->onkeyup
1 bajt zapisany: nie ma potrzeby końcowego ukośnika
2 bajty zapisane dzięki CraigAyre:
with()
funkcja2 bajty zapisane tylko dzięki ASCII:
key
zamiastwhich
4 bajtów zapisanych, ponieważ mamy tekst, nie ma potrzeby bo
'-'+
(bez tego każdy identyfikator jest unikalny) 1 bajt zapisany dzięki tylko ASCII (ponownie):>
koniec z zapisem 15 bajtów zapisanych dzięki apsillerom, jak powiedziano na górze mojej odpowiedzi.źródło
<body onkeydown=return!!alert(event.code)>
powinieneś załatwićfalse
keydown
Tcl / Tk, 22 znaki
Przykładowy przebieg:
Uwagi:
sprytnyprojektant umieścił przełącznik podświetlenia na swoim miejscu)źródło
Bash z X.org, 21 bajtów
Niestety nie mogę go przetestować, ponieważ korzystam z MacBooka w systemie Linux - bez PrntScr, bez klawiatury numerycznej i wszystkich innych.
xev
to narzędzie, które wyświetla zdarzenia myszy i klawiaturyX.org
. Przeciągam potokiem do awk, filtruję nawet linie (ponieważ każdy klawisz jest wyświetlany po naciśnięciu klawisza, a następnie po zwolnieniu) i wybieram tylko te, które zawierają(k
- ten ciąg znajduje się w każdej linii opisującej wciśnięty klawisz.źródło
showkey -s
tam: P) lub na czystym pulpicie GUI Wayland. To naprawdę bash + odpowiedź Xorga.C i Win32,
240224216205202194191 bajtówWyjścia
TAB:
F0008C00F0008
PAUSE:
450012C0450012
ENTER:
1C000CC01C000C
NUMPAD-ENTER:
11C000CC11C000C
WINDOWS-LEFT:
15B005AC15B005A
WINDOWS-RIGHT:
15C005DC15C005D
INSERT:
152002CC152002C
NUMPAD-INSERT:
52002CC052002C
Wyjaśnienie
Edycje
-16 dzięki @ugoren
-8: zmieniono
WNDCLASS
naint
tablicę, ponieważ wszystkie 10 elementów ma 4 bajty-11: częściowa inicjalizacja tablicy danych wndclass, zmniejszona do 9 elementów
-3: użyj niejawnej
int
deklaracji dla tablicy danych wndclass-8: usuń znak nowej linii z formatu wyjściowego (niewymagane w specyfikacji i od razu opróżnia printf bez niego); przejdź
RegisterClass
doCreateWindow
arg, używając returnATOM
; ustaw nazwę wndclass, nam
którą wystarczy zero bajtów, aby być poprawnym ciągiem.-3: ponownie
w
użyj var dlaMSG
danychźródło
<iostream>
+std::cout<<a^b<<"\n"
jest dłuższy. Ponadto myślę, że trzeba dodać typy zwracane do deklaracji funkcji im
nie może to być niejawneint
.for(;GetMessage(&m,0,16,0);)DispatchMessage(&m);
p(x,y,a,b)
i(void*)p
powinien oszczędzić trochę.Java (OpenJDK 8) , 369 bajtów
Nie można tego uruchomić z TIO, ponieważ używa interfejsu graficznego, ale działa na moim komputerze.
Niegolfowane / Objaśnienie:
źródło
setFocusTraversalKeysEnabled(false);
w twojej odpowiedzi to naprawi.Scala 2.10+, 279 znaków, 279 bajtów
To jest odpowiedź SCALA :) mimo że wydaje mi się, że robię Java. W każdym razie nie możemy przetestować tego na TIO.
To smutne, że musimy zadeklarować wszystkie odziedziczone metody, nawet jeśli ich nie używamy: czy mogę je usunąć z liczby bajtów, ponieważ niektóre flagi kompilatora mogą pozwolić na ich nie deklarowanie?
Spowoduje to wydrukowanie (jak w przypadku mojej odpowiedzi HTML-js) keyPressed, „-”, a następnie jego „lokalizacji”.
Na przykład :
PrtScn -> nie można zweryfikować
Scroll Lock -> 145-1
Pauza -> 19-1
lewy Shift -> 16-2
prawy Shift -> 16-3
lewy Ctrl -> 17-2
prawy Ctrl -> 17-3
Caps Lock -> 20-1
Tab -> nieweryfikowalny
Enter -> 10-1
Enter na klawiaturze numerycznej -> 10-4
Num Lock -> 144-4
Insert -> 96-1
Ins na klawiaturze numerycznej -> 96-4
Backspace -> 8-1
Del -> 127-1
F1 ... F12 -> 112-1 do 123-1
Esc -> 27-1
lewy klawisz Windows -> 524-2
prawy klawisz Windows -> 524-3
Alt -> 18- 2
AltGr -> 18-3 (rodzaj buggy, wykrywa 17-2, a następnie 18-3,ale tak naprawdę jest to 18-3)
klucz aplikacji (menu kontekstowe) -> 525-1
Chociaż myślę, że to zależy od komputera: / Jestem teraz na laptopie Azerty.
źródło
-std=c89
ponieważ współczesne kompilatory mają domyślnie c99 lub c11, ale nie trzeba tego liczyć. Więc nie jestem pewien, jaka byłaby decyzja z meta-golfa.TI-BASIC, 19 bajtów
Oto ilustracja pozostałych kluczy:
Wyjaśnienie:
Niestety nie jest to możliwe w Arnold C, więc musiałem trzymać się TI-BASICA.
źródło
C #, 144 + 601 = 745 bajtów
Składa się z dwóch klas, nie udało mi się połączyć ich w jedną klasę.
Główna klasa:
Klasa haka:
Wyjścia:
137
147
141
142
220
221
174
224
źródło
||
na|
i inne podobne golfa, ale mój mózg potrzebuje odpoczynku po tym!public int v;public int c;public int f;
można ją skrócić dopublic int v,c,f;
AutoHotkey , 26 bajtów
Nie można przetestować (tylko wygrana), ale
M
opcja mówiWięc powinno być dobrze.
źródło
WinApi C ( gcc ), 156 bajtów
Ten program drukuje kod wirtualnego klucza systemu Windows przypisany do każdego klawisza klawiatury.
\n
Wprintf
formacie-string jest opcjonalne (ale sprawia, że wyjście ludzki w obsłudze) i może zostać usunięta za łączną notą 154 bajtów . Łatwym sposobem na zabicie programu (bez taskmgr) jestCTRL + PAUSE
. Jeśli masz klawiaturę z klawiszem Fn, ten program nie może jej podnieść, ponieważ nie jest nawet zauważany przez system Windows.#include <d3d.h>
podstęp i inspirację dlaBYTE
tablicy.Program ze zmiennymi lokalnymi, czytelnością i bez ostrzeżeń kompilatora wygląda następująco:
źródło
C (gcc) + Win32, 94
9598105107110bajtyKod przechwytuje klucze nawet po utracie ostrości.
Następujące zrzuty ekranu są rejestrowane, dodając spacje między wyjściami (
printf("%d ",j);
+1 bajt) dla lepszej czytelności:Left-ctrl Left-win Left-alt Space Right-alt Right-win Right-menu Right-ctrl Left-shift Z X C Right-shift Left-shift 1 2 3 Num 1 Num 2 Num 3 Left-shift +/= (on the main part) Num + Left-alt PrtScn
Kod używa
GetAsyncKeyState
do sprawdzania stanu klucza bez sprawdzania kolejki komunikatów, zwykle w czasie rzeczywistym bardziej niż inne podejścia w trybie użytkownika (z wyjątkiem DirectInput). To podejście jest szeroko stosowane w keyloggerach.(j<16||j>18)
filtruje zwykłe Ctrl / Alt / Shift. 16/17/18 jest uruchamiany za każdym razem, gdy zostanie naciśnięty lewy lub prawy przycisk, wraz z wartością vkey określoną dla lokalizacji.źródło
PowerShell, 34 bajty
Wyjścia w tym samym wierszu co wejście, co może być nieco mylące.
źródło