답변:
원본 코드 :
[[ ! "${1////x}" =~ [[:alnum:]] ]]&&[[ $# = 1 ]]&&bash -c "$1"
입력:
__=; (( __++, __-- ));
(( ___ = __, ___++));
(( ____ = ___, ____++));
(( _____ = ____, _____++));
(( ______ = _____, ______++));
(( _______ = ______, _______++));
(( ________ = _______, ________++));
(( _________ = ________, _________++));
${!__##-} <<<\$\'\\$___$______$_______\\$___$______$_____\\$___$_______$__\\$___$_______$_________\'\ \$\'\\$___$___$__\\$___$______$_______\\$___$_______$______\\$___$_______$______\\$___$_______$_________,\ \\$___$____$_________\\$___$_______$_________\\$___$________$____\\$___$_______$______\\$___$______$______\\$__$______$___\'
설명:
이것은 "echo Hello, World!"를 인코딩합니다. 8 진 이스케이프 시퀀스 (\ xxx).
숫자를 사용할 수 없다는 점을 제외하고 첫 번째 부분은 숫자 0-7에 대한 변수를 작성합니다. 이것들을 사용하여 실제 명령을 내리는 것으로 평가되는 8 진 시퀀스로 문자열을 만들 수 있습니다.
그러나 eval
영숫자이기도합니다. 대신이 문자열을의 다른 인스턴스에 대한 입력으로 파이프합니다 bash
. $0
Bash를 호출하는 데 사용되는 명령의 이름을 포함합니다. Bash를 정상적으로 실행하는 경우 (TIO를 통해 또는 터미널에 붙여 넣음) 일반적으로 bash
(또는 -bash
로그인 쉘). (이것은 우연히 스크립트에 붙여 넣어서 실행하려고하면 여러 번 포크 자체를 시도 할 때 상황이 끔찍하게 잘못된다는 것을 의미합니다.)
그러나 어쨌든 $0
직접 말할 수는 없습니다 . 대신, $__
포함 이름 의 $0
( "0"), 그리고 당신은 (액세스에 대한 간접 확장을 사용할 수 ${!__}
의 내용을 의미를 $0
).
그리고 마지막으로 필요한 모든 것을 제공합니다.
•GG∍Mñ¡÷dÖéZ•2ô¹βƵ6B
-107
•GG∍Mñ¡÷dÖéZ• - big number
2ô - split into twos (base-10-digit-wise)
¹β - to base of input
B - convert to base (using 012...ABC...abc...):
Ƶ6 - 107 (ToBase10(FromBase255(6))+101 = 6+101 = 107)
〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ〡㋄ⶐ✐сᑀ⟙ⶐⶐ〡ސЀᶑ
sLƽ$Xṙ5O½Ọ
원래 코드는 다음과 같이 설명 될 수 있습니다.
sLƽ$Xṙ5O½Ọ Main link; argument is z
s Split z into n slices, where n is:
$
ƽ The integer square root of
L the length of z
X Random of a list. Returns a random row of the input put into a square
ṙ5 Rotate the list left 5 times
O Get codepoints
½ Floating-point square root
Ọ From codepoints
"Hello, World!" 코드 포인트를 가져 와서 제곱 한 다음 코드 포인트로 캐스트하고 오른쪽으로 5 번 회전 한 다음 결과를 제곱하고 평평하게 만듭니다.
이것이 올바른 해결책인지 확실하지 않은지 (TIO에서는 \00
문자를 인쇄합니다 ), 내 octave-cli
껍질에서는 다음과 같습니다.
또한 원래 도전에서는 아무것도 인쇄하지 않습니다 (또는 null 문자) 이므로 아무것도 같지 \00
않으면 괜찮습니다.
[72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33, 0]
0
으로10
).
Hello, World!
및 줄 바꿈을." 도전 과제의 정확한 인용문입니다. 그리고 실제로, 그것은 대답을 사소하게 만듭니다.
{length:1, charCodeAt:()=>(e='Hello, World!', String.fromCharCode=()=>'')}
꽤 쉬웠습니다.
Hello, World!
내부의 모든 것이 String.fromCharCode
4의 배수 만 반환 !
하고 문자 코드는 33이므로 문자열 입력을 출력 할 수 없다는 것을 알았습니다 . 따라서 분명히 전체 프로그램을 해킹해야합니다. 자바 스크립트로 내장 된 해킹은 그것들을 막으려 고하지 않는다면 사소한 일입니다 (그렇게하더라도 많은 해결 방법이 있습니다 ...).
호출 할 때마다 원하는 문자 만 반환하는 간단한 프록시입니다.
var i = 0;
var string = "Hello, World!";
var proxy = new Proxy([], {
get: function(target, property) {
if (!(++i%3)) {
return string[property];
}
return [1];
}
});
마술 입력은 : 1767707618171221 30191World!
1767707618171221
는 소수이며 밑 36에 쓰여 "hello"
있습니다. 대문자를 "Hello"
사용하면을 사용하여 인쇄됩니다.$><<
$><<", #$'"if/30191/
은 30191
입력 에서 숫자 를 찾고 쉼표, 공백 및 입력 뒤에 나오는 모든 것을 30191
( 뒤에서 $POSTMATCH
짧은 변형으로 참조되는)을 사용하여 문자열을 표준 출력에 씁니다 $'
.이것을 첫 번째 인수로 전달하십시오.
C=("").char;_G[C(112,114,105,110,116)](C(72,101,108,108,111,44,32,87,111,114,108,100,33))
원래 코드가 파일에 있다고 가정하고 tehtmi.lua
(bash 또는 유사한 쉘에서) 다음을 실행하십시오.
lua tehtmi.lua 'C=("").char;_G[C(112,114,105,110,116)](C(72,101,108,108,111,44,32,87,111,114,108,100,33))'
또한 TIO가 사용하는 Lua 5.3에서도 작동하므로 온라인에서 사용해 보지 않겠 습니까? "PUC-Rio 's Lua 5.1"코어를 사용하는 구현에 대해서는 테스트하지 않았지만 (실제로 정보를 찾을 수 없기 때문에) 내 솔루션도 작동합니다.
소문자가 5 개 미만인 경우에만 첫 번째 인수를 코드로 실행합니다.
트릭은 실행하는 것 print("Hello, World!")
입니다. 이것을 실행할 수있는 또 다른 방법 _G["print"]("Hello, World!")
은 문자열 만 사용하는을 사용하는 것입니다.
그러나 소문자 수 제한으로 인해 문자열을 직접 사용할 수는 없지만 일련의 바이트에서 문자열로 변환 할 ("").char
수있는 함수를 얻기 위해 실행할 string.char
수 있습니다. 우리가 모두 구성하는 데 사용할 수 있도록 (우리가 한도에 도달하지 않도록) I는 대문자 변수에 할당 print
하고, Hello, World!
위처럼 사용할 수있는 문자열.
next
대신 사용하려고 생각했습니다 char
.
입력은 다음을 포함하는 문자열이어야합니다.
e(
`\
_\
=\
>\
"\
H\
e\
l\
l\
o\
,\
\
W\
o\
r\
l\
d\
!\
"\
+\
\`
\`
`)
이것을 사용하여보십시오 :
const e=eval,p=''.split,c=''.slice,v=[].every,f=s=>(t=c.call(s),typeof s=='string'&&t.length<81&&v.call(p.call(t,`\n`),l=>l.length<3)&&e(t)(t))
input='e(\n`\\\n_\\\n=\\\n>\\\n\"\\\nH\\\ne\\\nl\\\nl\\\no\\\n,\\\n \\\nW\\\no\\\nr\\\nl\\\nd\\\n!\\\n\"\\\n+\\\n\\`\n\\`\n`)'
console.log(f(input))
출력의 후행 줄 바꿈 요구 사항에 신경 쓰지 않으면 마지막 6 줄을 대신 다음과 같이 바꿀 수 있습니다.
!"
`)
입력에 대한 제한 사항은 문자열이고 각 행의 길이는 2 바이트 이하이며 총 길이는 80 바이트 이하입니다. 올바르게 이해 한 후의 첫 번째 시도는 다음과 같습니다.
_
=>
`\
H\
e\
l\
l\
o\
,\
\
W\
o\
r\
l\
d\
!
`
참고 : \
s는 입력에서 문자열의 개행을 무시해야합니다. 이것은 대답에 엄청나게 중요하며, 우연히 대답했을 때 믿을 수 없습니다. (이전에 익숙했지만 잊어 버렸습니다)
그러나 =>
인수와 같은 줄에 있어야하기 때문에 이것은 효과가 없었습니다 . 고맙게도 문자열에 비슷한 것을 감싸고 입력을 평가하여 한 줄로 줄이면 최종 답변이됩니다. 입력에서 eval이 발생하면 다음이 문자열로 생성됩니다 (이는 함수로 평가 된 후 실행 됨).
_=>"Hello, World!"+`
`
이것은 깨지기 힘들었지 만 결국 성공했습니다.
또한 첫 균열!
나는 이것이 항상 위험하다고 생각하지만, 나는 인터프리터 (지금 막 컴파일)에 버그가 있다는 것이 정확하다고 기다리는 균열이 있다고 생각한다.
내 입력
0 1 0 10 10 10 10
Hello, World!\n\n\n\n\n\n\n\n\n\n.....
끝없는 줄 바꿈 이 출력됩니다 .
그러나 코드의 마지막 섹션을 보았습니다.
:1/1+1$(@6)7
메모장을 0x0A
무서운 방식 으로 (줄 바꿈)으로 설정하고 입력을면 7 (입력면)으로 읽은 다음 7면이 0이 될 때까지 6면 (메모장면)을 반복적으로 인쇄합니다. 면 7을 0으로 설정하면 줄 바꿈 하나만 얻어야합니다. 그러나 무한 줄 바꿈이 있고 13 번째 입력은 0이었습니다. 루프에 "7면의 인쇄 번호"를 삽입하여 7면이 항상 0인지 확인할 수 있습니다.
:1/1+1$(@6%7)7
그런 다음 끝없는 \n0
쌍을 인쇄합니다 .
입방체 github 페이지 의 사양을보고 있는데이 동작은 버그와 매우 끔찍합니다. 원래 프로그램의 마지막 문자 7
를 a에서 0
결과로 변경하면 예상 된 동작이 발생합니다. TIO 인터프리터는 동일한 잘못된 동작을 나타냅니다.
내가 찾은 해결책은 인쇄 할 수없는 문자를 매우 많이 사용하므로 여기에 붙여 넣으려고 시도해도 효과가 없었습니다. 입력의 바이트 값은 다음과 같습니다.
109, 89, 4, 121, 3, 11, 8, 29, 37, 38, 27, 25, 72, 4, 4, 4, 3, 3, 3, 4, 4, 37, 3, 27, 4, 3
또는 TIO 링크의 입력 필드에서 문자열 버전을 사용할 수 있습니다.
원래 프로그램은 입력에서 고유 한 문자를 사용한 다음 입력을 반전시키고 두 목록의 요소를 곱합니다. 따라서 첫 13 문자가 구분되고 마지막 13 문자가 모두 첫 13 문자에도 나타나고 각 인덱스 쌍이의 [i, 26-i]
i 번째 문자의 바이트 값에 곱한 26 자 길이의 문자열을 만들었습니다 Hello, World!
.
n[>n]<[8+o<]
2 25 92100106103 79 24 36103100100 93 64
여기 사용해보십시오페이지에서 줄 바꿈을 렌더링하지는 않지만 .
n
입력을 받고, 공백으로 나누고 int로 캐스트하려고하면 스택에 배치됩니다. o
서수를 인쇄하고 8+
생각한대로 수행합니다. 따라서 입력은 공백으로 나눠진 역순으로 코드 포인트보다 8 작아야합니다.
2
것입니다-herokuapp 페이지 만 렌더링하지 않습니까?
원본 코드 :
#define O(c)(((char**)v)+c)
#define W(c)*(O(c)-**O(2)+x)
main(x,v){puts(W(42));}
인수 :
"Hello, World!" ","
설명:
W(c)
인자 목록에서 문자열의 주소를 계산하여 인쇄합니다. O(c)
이 경우 42 번째 인수 인 cth 인수 ( ) 의 주소로 시작한 다음 두 번째 인수 ( **O(2)
) 의 첫 문자를 정수 오프셋으로 빼고 더합니다.x
수인을 더합니다.
W(c)
두 번째 인수를 사용하므로 적어도 3 개 (0, 1, 2)가 있어야한다는 것을 알고 있습니다. 그리고 "Hello, World!" 첫 번째 인수를 입력 한 다음이 인수를 처리하려면 ASCII 값이 "42-x + 3 = 1"방정식에 맞는 문자가 필요합니다. 그것은 ","입니다.
강제 변환이로 실패하도록 구문 분석 된 객체 의 valueOf()
및 toString()
메소드를 재정의합니다 TypeError
.
{"valueOf": 7, "toString": 7}
정답은, 52768,23입니다
설명이 약간 관련되어 있습니다.
00 c0 ;load address
20 fd ae jsr $aefd ; checks for comma
20 eb b7 jsr $b7eb ; reads arguments
이 코드는 먼저 쉼표 (구문 필요)를 확인한 다음 두 개의 인수를 읽습니다. 첫 번째 인수는 WORD이고 메모리 위치 0014 및 0015에 리틀 엔디안이 저장되어 있으며 후자는 X 레지스터에 저장됩니다.
8a TXA ;Store second argument into A (default register)
0a ASL ; bitshifts the second argument left (doubles it)
45 14 EOR $14 ; XOR that with the low byte of first argument
8d 21 c0 STA $c021 ; Drop that later in the program
입력을 사용하여 프로그램을 다시 작성하는 것은 매우 영리합니다. 결국 프로그램 끝에서 출력 루프에 대한 카운터를 다시 씁니다.
45 15 EOR $15 ; XOR that with the high byte of the first argument
85 15 STA $15 ; Put the result in $15
49 e5 EOR #$e5 ; XOR that with the number $e5
85 14 STA $14 ; Put that in $14
악의적 인 부분이 있습니다.
8e 18 d0 STX $d018 ; stores the original second argument in d018
C64에서 d018은 매우 중요한 바이트입니다. 화면 출력과 관련된 것들에 대한 기준점을 저장합니다. 여기를 참조 하십시오 를 . 이것이 잘못된 값을 얻으면 C64가 중단됩니다. 필요한 대소 문자를 인쇄하려면 $ 17이되어야합니다.
이제 출력 루프를 시작합니다 :
a0 00 ldy #$00 ; zeroes out the Y register
b1 14 lda ($14),y ; puts the memory referenced by the byte
; starting at $14 (remember that byte?)
; into the default register
20 d2 ff jsr $ffd2 ; calls the kernal routine to print the char stored in A
c8 iny ; increment Y
c0 0e cpy #$0e ; test for equality with the constant $0e
그 상수는 전에 쓰여진 것입니다. 루프가 얼마나 오래 실행되는지 명확하게 결정합니다. 이미 올바른 값이지만, 0e를 다시 붙여야합니다.
d0 f6 bne *-8 ; jump back 8 bytes if y and that constant weren't equal
60 rts ; ends the program
나머지는 메모리 주소 c025에서 시작하여 인쇄해야 할 정보입니다.
거기에서 수학을 따르고 있습니다.
$FF
습니다.
정답은
8 비트
코드는 다소 복잡하며 자체 수정이 많이 필요합니다. 따라서 완전히 리버스 엔지니어링하는 대신이를 사용하여 자체 크랙 할 수 있습니다.
발생한 코드를 이해하는 데 도움이되는 코드를 약간 더 유용하게 분해했습니다. 구문은 KickAssembler를위한 것입니다.
*=$c000 // LOAD ADDRESS
jsr $aefd //checks for a comma
jsr $ad9e /*Reads in an argument. Stores length of it into
$61, with the address of the stored arg in $62-3*/
jsr $b6a3 /*Evaluates the string, leaving the pointer on $22-3
and the length on A*/ //I think
ldy #$00
loop: lda thedata,y
cpy #$01
beq shuffle
cpy #$07
beq shuffle
cpy #$0b
beq shuffle
tricks: jsr output
iny
bne loop
output: eor ($22),y //XOR's A with the y-eth letter of our input
jmp $ffd2 //good old CHROUT, returns to tricks above
thedata: .byte $f0,$48,$fa,$a2, $1c,$6d,$72,$30
.byte $06,$a9,$03,$48,$7c,$a3
shuffle: sta $c048 //drops A in mystery+4, over the constant
lda $c026,y
sta $c045 //overwrites the low byte of mystery
lda $c027,y
sta $c046 //overwrites the high byte of mystery
ldx #$00
mystery: lda $aefd,x
eor #$23
jsr output
iny
inx
cpx #$03
bne mystery
cpy #$0e
bne loop
eor #$1a
sta $d018
rts
이와 같이 라벨을 지정하면 코드 XOR에 필요한 상수를 인쇄하기 위해 숨겨져있는 많은 상수가 있음을 알 수 있습니다. XOR은 가역적이므로 원하는 출력을 입력하면 키가 무엇인지 알려줍니다.
그래서 마지막 줄을 바꿨습니다
/*from sta $d018
to*/ jsr $ffd2
따라서 잘못된 입력에서 충돌하지 않고 마지막으로 필요한 입력을 인쇄합니다.
그게 다야!
관심이 있다면 코드를 더 많이 해독합니다.
vice
. 그러나 그것이 올바른 해결책입니다.
drops A in mystery+1, over the constant
"<-실제로 mystery+4
는 레이블이 있습니다. 코드에서 RAM으로 실행되는 한, 가장 큰 문제 는 바이트 단위 입니다.
원본 코드 :
œ?“¥ĊɲṢŻ;^»œ?@€⁸ḊFmṪ⁷
입력:
1,2586391,2949273,3312154,3312154,1134001,362881,2223505,766081,1134001,1497601,3312154,1860601,140
설명:
주로 코드의 기능을 이해해야합니다. 가장 먼저하는 일은 문자열을 취하는 것입니다.
"!,Word Hel"
(개행 문자를 제외한 모든 필수 문자 포함) 및 순열을 많이 만듭니다. 입력은 순열 수를 지정하고 입력의 각 순열 쌍은 첫 번째 순열이 먼저 적용되는 문자열 배정 쌍에 적용됩니다. 기본적으로 P2 (P1 (S)), P2 (P2 (S), P2 (P3 (S)), ..., P2 (PN (S)), P3 (P1 (S)), ..., P3 (PN (S)), ... ..., PN (P1 (S)), ..., PN (PN (S)). 모두 연결되어 있으며 마지막 입력은 매 PNth마다 다시 사용됩니다. 이 큰 문자열의 문자이므로 PN = len (S) * N = 10 * N을 사용합니다. 이는 P3 (P1 (S)의 첫 번째 문자 인 P2 (P1 (S))의 첫 번째 문자를 사용한다는 의미입니다. )), PN (P1 (S))의 첫 문자까지 끝까지 더 단순화하기 위해 P1 = 1을 항등 순열로 설정 한 다음 "H"를 첫 번째로 순열하는 P2를 선택하면 충분합니다. 위치, "e"를 첫 번째 위치로 치환하는 P3 등. 운 좋게도 PN에 대해 이미 선택된 것과 같은 작은 순열 숫자는 문자열의 이전 문자에 영향을 미치지 않으므로 PN은 "!"로 남습니다. 문자열의 시작 부분에. (이것이 사실이 아닌 경우, 다른 P1을 선택하여 해결할 수 있습니다.)
4195875
두 번째 인수를 문자열로 인쇄하려고 시도하는데 입력에서 결정할 수있는 포인터입니다. 위치 메모리 4195875
에서 "Hello, World!\n"
문자열을 시작하는 경우도 마찬가지 입니다.
수를 첨가하여 측정 하였다 print("%p", "Hello, World!");
전과 printf
진수로 16 진수로 변환하여 원래 TIO에 그것을 시도. 그러나 printf
형식 문자열을 보여 줍니다. 몇 가지 숫자를 시도하여 문자열이 형식 문자열 앞에 있다는 것을 알았습니다.
따라서 메모리에서 다음과 같이 보입니다 (C 문자열).
Hello, World!\n\0%2$s\0
또한 컴파일러를 업데이트하면 솔루션이 손상 될 수 있습니다.
[1, "HH", 1, "eellloo", 1, ",,", 1, " WWoo", 1, "rr", 1, "ll", 1, "dd", 1, "!!"]
설명이 조금옵니다 ...
var i = 0;
var string = `"${t}"`;
var answer = "i++?0:q=string";
console.log( f(answer) );
PDO,FETCH_CLASSTYPE
(TIO에는 PDO 클래스가 정의되어 있지 않으므로 위의 데모는 코드 패드를 사용합니다)
다른 해결책 :
ReflectionFunction,IS_DEPRECATED
81 자의 글자 수 한도를 감안할 때 이것은 의도 된 해결책이 아닐 수도 있습니다
global.g = ()=>"Hello, World!";
var str = "g";