Kwadraty steganograficzne
Twoim zadaniem jest pobranie ciągu i wygenerowanie NxN
obrazu reprezentującego ten ciąg. Musisz także napisać algorytm, który pobiera obraz i przekształca go z powrotem w ciąg znaków. Punktacja będzie obejmować liczbę bajtów obu algorytmów:
Algorytm „szyfrowania” + algorytm „deszyfrowania” .
Powinieneś wysłać każdy osobno, z liczbą bajtów dla algorytmów szyfrowania i deszyfrowania wyświetlanych osobno.
Przykładowy algorytm
Na przykład oto „Programowanie zagadek i golfa kodowego” przy użyciu prostego algorytmu steganograficznego opartego na ASCII w kanale Blue:
#2e7250,#6ea972,#04eb6f,#0fc767,#74ab72,#ee6161
#b73b6d,#1aae6d,#f37169,#bda56e,#1fe367,#e99620
#706450,#0d3575,#146b7a,#4ea47a,#2a856c,#95d065
#3f2d73,#cef720,#bab661,#d1b86e,#f22564,#12b820
#0f3d43,#c86e6f,#1ee864,#a66565,#247c20,#c3bb47
#0e296f,#89d46c,#585b66,#c08f20,#455c20,#136f20
Możesz zobaczyć, że niebieski kanał po prostu przechowuje wartości ascii dla tego obrazu:
50 = 80(P) 72 = 114(r) 6f = 111(o) 67 = 103(g) 72 = 114(r) 61 = 97(a)
6d = 109(m) 6d = 109(m) 69 = 105(i) 6e = 110(n) 67 = 103(g) 20 = 32( )
50 = 80(P) 75 = 117(u) 7a = 122(z) 7a = 122(z) 6c = 108(l) 65 = 101(e)
73 = 115(s) 20 = 32( ) 61 = 97(a) 6e = 110(n) 64 = 100(d) 20 = 32( )
43 = 67(C) 6f = 111(o) 64 = 100(d) 65 = 101(e) 20 = 32( ) 47 = 71(G)
6f = 111(o) 6c = 108(l) 66 = 102(f) 20 = 32( ) 20 = 32( ) 20 = 32( )
Podczas gdy pozostałe kanały przechowują losowo generowane wartości, aby „urozmaicić” różnorodność kolorów na obrazie. Wyciągając wiadomość z obrazu, możemy po prostu zignorować inne wartości kanału i wyciągnąć bit szesnastkowy z niebieskiego kanału, rekonstruując ciąg:
"Programming Puzzles and Code Golf"
Zwróć uwagę, że spacje użyte do wypełnienia łańcucha w kwadracie nie są uwzględniane w końcowym odszyfrowanym wyjściu. Chociaż musisz wstawić ciąg znaków na obrazie, możesz założyć, że ciąg wejściowy nie będzie kończył się spacjami.
Zasady
- Musisz zakodować 1 znak na piksel, kanał wybrany do zakodowania znaku jest dowolny.
- Kanały pozostałych kolorów RGB muszą być losowe, inne niż ten, w którym chcesz zakodować ciąg; oznacza to, że Twoje ostateczne niekodowane kanały musiałyby znajdować się pomiędzy
0x0000-0xFFFF
(losowo wybrane). - Wyrażenie końcowego wyniku jako tablicy 2D wartości kolorów RGB jest w porządku
0x000000-0xFFFFFF
, nie trzeba używać tworzenia obrazu, chyba że chcesz się dobrze bawić lub jeśli jest mniej bajtów. Jeśli wybierzesz wyjście jako ciągi szesnastkowe, poprzedź ciąg szesnastkowy za pomocą#
EG#FFFFFF
lub#05AB1E
. Możesz oddzielić tabulatory, przecinki lub cokolwiek innego, co byłoby rozsądne w poziomie, ale musi zachować kwadratowy wzór; innymi słowy, musisz zastosować odpowiednią separację nowego wiersza. - Dane wyjściowe muszą być w kwadracie, a łańcuch musi być wypełniony spacjami na końcu, aby to uwzględnić. To znaczy że
N≈SQRT(Input#Length())
. Jeśli długość wejściowa nie jest idealnym kwadratem, należy zaokrąglić w góręN
i wstawić spacje. - Jak wspomniano wcześniej, jeśli wypełniasz spacje obrazem, nie możesz umieszczać znaków dopełnianych na końcowym wyjściu „odszyfrowanym”.
- Możesz założyć, że:
- Łańcuch wejściowy nie kończy się spacjami.
- Łańcuch wejściowy będzie używał tylko drukowalnych znaków ASCII.
- To jest golf golfowy , wygrywa najmniej bajtów.
źródło
Odpowiedzi:
05AB1E , 34 + 12 = 46 bajtów
Wykorzystuje czerwony kanał.
05AB1E używa CP-1252 kodowanie .
Kodować:
Wypróbuj online!
Rozszyfrować:
Wypróbuj online!
Alternatywna metoda wypełniania z jednakową liczbą bajtów
źródło
C, 201 (kodowanie) + 175 (dekodowanie) = 376 bajtów
Aby zakodować:
Koduje każdy znak ciągu wejściowego w zielonym kanale widma RGB, jednocześnie ustawiając dwa pozostałe kanały jako losowe wartości szesnastkowe. Pobiera dane wejściowe przez STDIN jako ciąg znaków i wysyła do STDOUT ciąg wielu linii szesnastkowego kodu koloru w kształcie kwadratu. Zakładając, że masz zainstalowany Python 3 i ImageMagick, a powyższy plik jest kompilowany do pliku o nazwie
a.out
w bieżącym katalogu roboczym (CWD), możesz bezpośrednio uzyskać obraz wynikowy o nazwieOutput.png
, do CWD z tekstu wyjściowego za pomocą następującego polecenia:Oto przykładowy obraz wyjściowy utworzony przez powyższą komendę
Programming Puzzles and Code Golf
jako ciąg wejściowy:Aby zdekodować:
Pobiera dane wejściowe przez STDIN sekwencję rozdzielonych spacjami ciągów znaków w kolorze heksadecymalnym, z których każdy jest zamknięty w podwójnych cudzysłowach (
"
) (char** argv
inmain
), a także po wywołaniu wmain
,int argc
dla wprowadzania liczb całkowitych. Wysyła do STDOUT ciąg jedno- / wieloliniowy reprezentujący zdekodowany komunikat.Z czasem spróbuję zagrać w golfa, kiedykolwiek i gdziekolwiek będę mógł.
Ponadto, jeśli obie metody są takie same w tym samym pliku, można użyć następującej
main
metody, aby połączyć wszystko z każdą funkcją otrzymującą prawidłowe dane wejściowe:i używając tego, do kodowania musisz podać
E
jako pierwszy argument wywołujący metodę kodowania, a następnie argument o pojedynczym ciągu, podczas gdy do dekodowania wystarczy podać sekwencję rozdzielonych spacjami ciągów kodu koloru szesnastkowego z każdym z nich zamkniętym w podwójne cudzysłowy ("
).Wreszcie, jeśli chcesz, możesz uzyskać w pełni przygotowaną, gotową do użycia wersję tutaj , chociaż nie jest golfa, ale także nie wyświetla żadnych ostrzeżeń ani błędów po kompilacji.
źródło
Python 2,
164160 +9493 = 253 bajtówOszczędność 1 + 1 bajtu dzięki Kreatorowi pszenicy.
-5 bajtów dzięki Kade
Koder: ciąg musi być ujęty w cudzysłów, np.
"CodeGolf"
Wyjście jest kolorowym obrazem PPC ascii.Dekoder: Pobiera wejściową nazwę pliku jako argument wiersza poleceń
Stosowanie:
Przykład:
Programowanie zagadek i Code Golf
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
źródło
for
int
z tego jest 4, które jest następnie+1
edytowane, więc 5-1
.print
i'
w dekoderze. Jestem też całkiem pewien, że możesz zrobić,int((len(s)+1)**.5)
aby zaoszczędzić trochę bajtów.' '.join("%d %d %d"
na,''.join(3*"%d "
ponieważ jestem pewien, że końcowe miejsce jest OK.Scala, 97 + 68 = 165 bajtów
Szyfrowanie (97 bajtów):
Bierze ciąg i ponownie stroi iterator sekwencji liczb całkowitych.
Deszyfrowanie (68 bajtów):
Pobiera iterator sekwencji liczb całkowitych i zwraca ciąg znaków.
Wyjaśnienie:
.
źródło
Perl, (103 + 1) + (36 + 2) = 142 bajty
Koder tekstu na obraz (uruchamiany z
-p
karą 1-bajtową;-p0
(dodatkowy bajt kar) jest konieczny, jeśli chcesz obsługiwać znaki nowej linii w ciągu wejściowym):Dekoder obrazu do tekstu (uruchamiany z
-p0
karą 2-bajtową):Używa
#abcdef
tekstowego formatu obrazu i koduje w niebieskim kanale. Oto przykład możliwego wyniku podanegoProgramming Puzzles and Code Golf
jako dane wejściowe:Objaśnienie enkodera:
Byłem bardzo zadowolony z tego zastosowania
\K
; określa miejsce zamiany i umieszczenie go w pętli wydaje się, że liczy się wystąpienie ostatniej iteracji w pętli. Dopasuje więcs/(.*?\K,){$a}/\n/g
ciąg o minimalnej długości w postaci cokolwiek przecinek cokolwiek przecinek… cokolwiek przecinek, który ma$a
przecinki, ale faktycznie zastąpiona część dopasowania będzie po prostu ostatnim przecinkiem. Powoduje to zastąpienie każdego$a
przecinka nową linią, co daje nam kwadratowy kształt obrazu.Dużą zaletą Perla do tego wyzwania (innego niż wbudowany konwerter znaków na szesnastkowy, który był niezwykle wygodny) jest to, że ma bardzo krótki dekoder (tak krótki, że chociaż Perl ma wbudowaną funkcję konwertując szesnastkowy na ciąg, krócej było go nie używać). Oto jak to działa:
Jedynymi przypadkami dwóch znaków bezpośrednio przed znakiem niealfanumerycznym są niebieskie kanały (które chcemy rozpakować), które pojawiają się tuż przed przecinkami i znakami nowej linii; oraz dwie postacie, które pojawiają się przed sobą
#
niż pierwsza. Nie chcemy drugiej kategorii meczów, ale nieuchronnie pokrywają się z poprzednią kategorią, a zatem zostaną wykluczone przez kontrolę nakładających się meczów.źródło
MySQL, 438 + 237 = 675 bajtów
Na końcu danych wyjściowych znajduje się nowy wiersz, ale nie pojawia się on po odszyfrowaniu. Funkcja szesnastkowa (przeciążenie liczb całkowitych) odetnie wiodące zera, więc musiałem uzupełnić ją ciągiem 0. Mogłem zapisać niektóre bajty, gdybym mógł zadeklarować obie funkcje między ogranicznikami.
Szyfruj
Odszyfruj
Stosowanie:
źródło
C #, 312 + 142 = 454 bajtów
Kodowanie:
Rozszyfrowanie:
Pełny program:
źródło
Mathematica, 111 + 65 = 176 bajtów
Enkoder
Dekoder
źródło
Przetwarzanie,
220209194 +171167151 =391380376361345 bajtówAktualizacja:
Usunięto bezużyteczne
noStroke()
i uczyniono jedno-wyciągowe dla obu pętli for.Usunięty bezużyteczny
image(p,0,0);
, podał deszyfratorowi nazwę pliku jako parametrAlgorytm szyfrowania
Wywołanie funkcji:
g("Programming Puzzles and Code Golf");
Jest to funkcja, która pobiera ciąg znaków i tworzy wynik przed zapisaniem go jako
t.png
. Wykorzystujered
wartość do przechowywania ukrytego tekstu.Algorytm deszyfrowania
Funkcja wywołania przez:
u(file_name);
Jest to również funkcja, która wyszukuje obraz określony przez parametr, a następnie wyświetla ukryty ciąg (ponieważ jest krótszy niż zwracanie ciągu).
Rozszerzony kod
(Algorytm szyfrowania)
Ciąg jest przekazywany po wywołaniu funkcji. Pierwszy wiersz funkcji oblicza długość boku kwadratu, biorąc
ceil
pierwiastek kwadratowy. Następnie wchodzimy do pętli for, w której ustawiamystroke
(kolor krawędzi), aby wartość ASCII znaku była czerwona, a losowe wartości dla niebieskiego i zielonego. Po wykonaniu tej czynności tworzymyrect
(prostokąt) o szerokości =1
i wysokości =1
, tj. Pikselu (z jakiegoś dziwnego powodu nie mogępoint
prawidłowo użyć ). W ostatnim wierszu powstały obraz jest następnie zapisywany jakot.png
.(Algorytm deszyfrowania)
Ta funkcja ma nazwę pliku jako parametr (jako ciąg znaków). Następnie obraz w pliku jest przechowywany w zmiennej do późniejszego wykorzystania. Po zakończeniu tej czynności ustawiamy ciąg na
""
zamiast tworzyć nowy ciąg tylko po to, aby zatrzymać ukryty ciąg. Następnie iterujemy obraz za pomocą dwóch zagnieżdżonych pętli for i dodajemy do łańcucha wartość znakową czerwonej wartości piksela. Na koniec drukujemy powstały ciąg po usunięciu z niego spacji wiodących (za pomocą wyrażenia regularnego). Powodem, dla którego drukujemy ukryty tekst zamiast go zwracać, jest to, że w ten sposób jest on krótszy i oszczędzamy bajty.Zaszyfrowany surowy tekst wyzwania:
źródło
Galaretka, 40 + 20 = 60 bajtów na stronie kodowej Jelly
Koder (tekst → obraz):
Wypróbuj online!
Dekoder (obraz → tekst):
Wypróbuj online!
Przykładowe dane wyjściowe, które program może wygenerować (przechowuje informacje w czerwonym kanale):
W tych większych wyzwaniach zwięzłość Jelly zaczyna nieco opadać, potrzebując kilku postaci „strukturalnych”, aby rozwiązać dwuznaczności parsowania, ale mimo to jest bardzo zwięzła. Oto jak działa koder:
A oto jak działa dekoder:
źródło