JavaScript의 내장 문자열은 무엇입니까?


147

이 질문은 질문 제목에 요약하기 어렵습니다

업데이트이 질문에서 추출한 문자를 기반으로 입력에서 난독 처리 된 문자열을 작성하는 JSFiddle을 만들었습니다. 여기에 액세스 할 수 있습니까 , 아니면 요점 이 더 쉬울까요?

최근 에이 프로필 에서 다음과 같은 재미있는 난독 화 JavaScript를 보았습니다 .

javascript:[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-
[])[1<<1]+[/~/+{}][+!1][-~1<<1]+([]+/-/[(!!1+[])[1>>1]+(!!1
+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+([,][
~1]+[])[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+(/1/+
1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</[1]+[])[1/1.1&1]

놀람을 망쳐 서 미안하지만 이것이 평가되면 다음을 반환합니다

"I love you" in Chrome
"I lone you" In Firefox
"I lo[e you" in IE10

이것이 작동 할 때의 작동 방식은 일련의 메시지를 생성하고 이와 같이 문자를 빼내는 것입니다 (예 : "I"사용).

[]+1/!1
returns
"Infinity"
then
[[]+1/!1]
creates this array:
["Infinity"]
then
[[]+1/!1][1^1]
Takes the first (1^1 == 0) element of that array
"Infinity"
finally
[[]+1/!1][1^1][1>>1]
Takes the first (1>>1 == 0) char of that string
"I"

생성되는 다른 문자열은 다음과 같습니다.

({}+[])       -> "[object Object]" (where the space comes from)
([]+!!-[])    -> "false" (used for it's "l")
[/~/+{}][+!1] -> "/~/[object Object]" (this is used for an "o")
(/<</[1]+[])  -> "undefined"

나는 "n"과 "["의 대체물을 찾는 데 관심이 있었고 이것을 생각해 냈습니다.

String.fromCharCode(('1'.charCodeAt(0)<<1)+(10<<1))

1과 0을 사용하는 느낌에서 느끼지만 문자열과 전혀 관련이없는 것처럼 보이는 원래 코드의보다 우아한 측면 중 하나를 위반합니다. 다른 사람이 원래 난독 화 된 코드와 일치하는 "v"를 생성하는 방법에 대한 아이디어가 있습니까?

여기에 많은 유능한 JavaScript 프로그래머가 이것을 자세히 살펴본 후에 발견 된 추가 정보가 있습니다.

Firefox는 다음 줄 때문에 "고독"을 반환합니다.

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+

[1^11<<1] 이로부터 특정 문자를 잘라냅니다.

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])

이것은 다음과 같이 평가됩니다.

"function test() {
    [native code]
}"

"V"가있는 것 같습니다 !!!

동일한 코드에서 다음을 반환하므로 Chrome은 '사랑합니다'를 반환합니다.

"function test() { [native code] }"

"실제 프로그래밍 문제"와의 의심스러운 연결에 대한 질문이 종결되기 전에 @ Supr 's , @ Cory 's@ alpha123 ' s에 기반한 요약 된 솔루션을 추가한다고 생각했습니다 .

alert([[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+(
[]+!!-[])[1<<1]+[/~/+{}][+!1][-~1<<1]+[([]+/-/[(
!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(
!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],([]+/-/[(!!1+[
])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[
])[1^1]])[1^11<<1],([]+/-/[(!!1+[])[1>>1]+(!!1+[
])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11
+1+1)<<1]][((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<
1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1
)+1<<1]==({}+[])[1^1])*1)+((([]+/-/[(!!1+[])[1>>
1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1
]])[(1^11<<1)-1]==({}+[])[1^1])<<1)]+([,][~1]+[]
)[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+
(/1/+1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</
[1]+[])[1/1.1&1])

코드와 메시지의 복잡성을 감안할 때 JavaScript 엔진이 느끼는 것이 얼마나 특별하다고 말하는 것과 거의 같습니다. :)


9
Chrome 콘솔에 "사랑"이라고 표시되어 있습니다. i.imgur.com/rVyKMoP.png
bfavaretto

2
에서 문자가 아닌 문자를 제거하면 문자를 function test() { [native code] }정규화하고 원하는 문자를 추출 할 수 있습니다.
Jason Sperske

4
난독 화 코드를 사용하여 메시지를 인쇄하기 위해 비표준으로 정의 된 문자열 출력을 기반으로 한 코드 ...이 방법을 너무 현지화했습니다.

2
@ 이안, 사실. 내 인생에서 내가 사랑하는 사람들이 정말 나를 걱정한다면 Chrome을 사용하게 될 것입니다.
Jason Sperske 18.40에

4
이것에 대한 가장 좋은 부분은 내 텍스트 편집기가 경고하는 것입니다 : " '혼란스러운 사용!'"
Jake Johnson

답변:


83

우선, 저 재미있는 스 니펫을 가지고 놀아 준 Jason과 모든 기고자들에게 감사하고 싶습니다. 2 월 14 일에 아내에게 보내려고 재미있게 코드를 작성했습니다. :) 랩톱에 Chrome 만 설치하면 Firefox 및 IE에서 작동 방식을 확인할 수있는 옵션이 없습니다. 게다가, 내장 toString()메소드의 표현이 다른 브라우저에서 다르게 보일 것으로 예상하지 못했습니다 .

이제 실제 문제로 이동 하여 코드를 정확하게 살펴 보겠습니다. 그렇습니다 "v". 여기에는 "문제"가있었습니다. [native code]내장 된 방법에서 가져올 수있는 구문 분석 문자열을 제외 하고는이 편지를 얻는 다른 방법을 찾지 못했습니다 . 문자열과 숫자를 1사용 하지 않고 자신을 제한했기 때문에 이름에 사용 가능한 문자 만있는 방법을 사용해야했습니다.

사용 가능한 문자가 시작에서 기존 키워드와 문자열 표현, 즉 얻을 수 있습니다 우리했다 NaN, null, undefined, Infinity, true, false,와 "[object Object]". 일부는 쉽게 문자열로 변환 할 수 있습니다 (예 : 1/!1+[]gives) "Infinity".

배열 [], 객체 {}, 정규 표현식 /(?:)/, 숫자 1.1, 문자열에 대한 다양한 내장 메소드를 분석 "1"하고 RegExp라는 아름다운 객체 메소드를 발견했습니다 test(). 그 이름은 예, 사용할 수있는 모든 문자에서 조립 될 수 "t""e"에서 true, 그리고 "s"에서 false. 문자열 "test"을 만들고이 /-/줄에서 올바르게 식별 된 정규 표현식 리터럴에 대괄호 표기법을 사용 하여이 방법을 해결했습니다 .

/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]]

이미 언급했듯이이 코드는 Chrome에서 다음과 같이 평가됩니다.

function test() { [native code] }

Firefox에서 다음과 같이 :

function test() {
    [native code]
}

그리고 IE에서 :

 function test() {     [native code] }  

(후자 는 키워드 앞에 공백에 특별한 주의를 기울이십시오 function)

분명히 알 수 있듯이, 내 코드는 제시 된 문자열에서 24 번째 문자를 얻었습니다. "v"계획 된대로 Chrome 에서는 있지만 불행히도 Firefox 및 IE "n"에서는 "["각각 다릅니다.

모든 브라우저에서 동일한 결과를 얻으 려면 다른 답변에서 설명한 것과 다른 접근법 을 사용했습니다 . 이제 수정 된 버전은 다음과 같습니다.

javascript:[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-
[])[1<<1]+[/~/+{}][+!1][-~1<<1]+/\[[^1]+\]/[([]+![])[1<<1<<
1]+(/|/[(1+{})[1+11>>>1]+[[]+{}][+!1][1]+([]+1/[])[1<<1>>1]
+([1<1]+[])[1+11>>>1+1]+[[!!1]+1][+[]][1-1]+([]+!!/!/)[1|1]
+(/1/[1]+[])[!1%1]+(-{}+{})[-1+1e1-1]+(1+[!!1])[1]+([]+1+{}
)[1<<1]+[!!/!!/+[]][+[]][1&1]]+/=/)[1e1+(1<<1|1)+(([]+/-/[(
!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1
]])[1^1]==+!1)]+(!![]+{})[1|1<<1]+[1+{}+1][!1+!1][(11>>1)+1
]](([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+
(!!1+[])[1^1]]))[1&.1][11>>>1]+([,][~1]+[])[1-~1]+[[]+{}][!
1.1%1][11111.1%11.1*111e11|!1]+(/1/+1/[1<1][1%1])[1^11]+[[]
,[]+{}][1<<1>>>1][1||1]+(/[<+>]/[1&1|1]+[1.1])[1/11.1&1.11]

그러나 독자들에게 흥미를주기 위해 나는 이에 대한 해결책을 제공하지 않을 것이다. 나는 솔직히 당신이 그것이 어떻게 작동하는지 쉽게 이해할 것이라고 믿습니다.

PS 또 다른 난 독자

보편적 인 난독 화 도구를 만들려는 Jason의 아이디어에서 영감을 얻어서 하나 더 작성했습니다. 당신은 그것을 찾을 수 있습니다 : JSBin http://jsbin.com/amecoq/2 . 숫자 [0-9], 작은 라틴 문자 [a-z]및 공백 이 포함 된 텍스트를 난독 처리 할 수 ​​있습니다 . 문자열 길이는 주로 RAM으로 제한됩니다 (적어도 내 대답의 본문은 난독 화되었습니다). 출력은 Chrome, Firefox 및 IE에서 지원됩니다.

힌트 : 이 도구는 위에 제시된 것과 다른 난독 화 방식을 사용합니다.


4
"생성자"... 와우 대단하고 유효한 줄 바꿈으로 완벽한 사각형을 유지했습니다. 당신은 좋다
Jason Sperske

1
스타일 규칙에 따라 문자열을 생성하는 Obfuscator를 만들었습니다. jsfiddle.net/w9rFF/8
Jason Sperske

@JasonSperske 좋은 트릭이었습니다! 훌륭한 일! 그것에 기여하려고 노력할 것입니다.
VisioN

26

native code질문 의 비트 가 사용되지 않는 이유는 무엇 입니까? 이것은 'v'Chrome과 Firefox에서 모두 제공합니다 .

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]>([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]?([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]:([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]

IE를 지원하도록 편집하고 삼항 연산자없이 수행하십시오. 이것은 Chrome, IE 및 FF에서 작동합니다. 배열을 만들고 ==브라우저를 결정 하는 데 사용합니다.

[([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1],([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]][((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1)+1<<1]==({}+[])[1^1])*1)+((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)-1]==({}+[])[1^1])<<1)]

읽을 수있는 :

[
    //ie
    ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],
    //ch
    ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1],
    //ff
    ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]
]
[
    //ch?
    ((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1)+1<<1]==({}+[])[1^1])*1)+
    //ff?
    ((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)-1]==({}+[])[1^1])<<1)
]

그것 참 흥미 롭네. 원래 Firefox와 Chrome 사이에서 "기본 코드"라는 단어의 위치를 ​​예측할 수 없었습니다. 이것은 해결하지만 IE10 ( "i"를 반환하는 곳)에서는 작동하지 않습니다.
그래도이

아이디어는 둘 다 선택 n하고 v가장 큰 것을 선택하는 것입니다 str[23]>str[27]?str[23]:str[27]. 다시 말해, 3 차 연산자는 속임수입니다. IE도 지원하도록 확장 될 수 있습니다 :([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)]
Supr

1
귀하의 답변은 첫 번째 (원래 코드 작성자에게 앞서) 있었지만 그의 대답은 논리적으로 올바른 것으로 간주 될 수 있다고 생각했습니다. 여전히 훌륭한 직업 (그리고 잘된 13 표)
Jason Sperske

1
작은 nitpick : 3 차 연산자는 1 차 및 2 차 이후 세 번째로 중요한 연산자입니다. 세 개의 피연산자를 취하는 연산자는 삼항입니다.
Eric Lippert

1
@EricLippert, gah, 나는 올바른 용어를 사용하고 있는지 확인하기 위해 그것을 구글 검색했지만 여전히 잘못된 단어로 끝났습니다! 고마워요
Supr

8

이것은 내가 얻을 수있는 한 가깝습니다. 불행히도 그것은 다음을 호출하여 원래 난독 화의 규칙을 위반합니다 unescape().

unescape((/%/+[])[1]+(/1/[1]+[])[1%1]+(+!1)+(+!1)+(1e1+(11*(1-~1)<<1)))

해체 :

(/%/+[])[1]          => "%"
(/1/[1]+[])[1%1]     => "u"
(+!1)                => "0"
(+!1)                => "0"
(1e1+(11*(1-~1)<<1)) => "76"
===========================
unescape("%u0076")   => "v"

다른 아이디어 :

  1. 어떻게 든 unescape("\x76")
  2. 어떻게 든 118전화하지 않고 변환String.fromCharCode()
  3. "Invalid"라는 단어가 포함 된 예외에서 텍스트를 가져옵니다.

업데이트 :

코드 골프를 시작하여 더 짧게 만들고 부품을 더 많이 교체하는 1등의 작업을 수행했습니다.


나는 이것도 좋아한다. 나는 당신과 @ alpha123의 모습이 매우 난독 화되고 원래 의도를 영리하게 숨기므로 "올바른"답변에서 조금 찢어졌습니다.
Jason Sperske

그리고 IE10 지원은 거래를 봉쇄합니다 (훌륭한 답변을 위해 @ alpha123을 진심으로 사과드립니다)
Jason Sperske

따옴표 '%'(/%/+[[]+1/!1])[1]제거하여 바꿀 수 있습니다. 또한 l=unescape;소문자 L를 사용하여에 대한 참조를 숨겼습니다 unescape. 이것은 재미 있었다 :)
Jason Sperske

@JasonSperske : 더 짧음 :(/%/+[])[1]
Cᴏʀʏ

1
또는 변수의 이름을 지정할 수 있습니다 $1.
Cᴏʀʏ

4

n / v를 생성하는 부분은 다음과 같습니다.

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]

파이어 폭스에서 ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])평가

"function test() {
    [native code]
}"

Chrome에서 그것은

"function test() { [native code] }"

1^11<<1 따라서 Firefox의 추가 공백으로 인해 이것은 'v'에 도달하기에 충분하지 않으며 대신 'n'입니다.

그리고 이것이 Function # toString 동작에 의존해서는 안되는 이유입니다. ;)

편집 : 마지막으로 합리적으로 난독 화 된 크로스 브라우저 버전을 발견했습니다.

[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-[])[1<<1]+[/~/+{}][+!1][-~1<<1]+([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)+(parseInt("010")<10?(1+1+1+1):0)]+([,][~1]+[])[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+(/1/+1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</[1]+[])[1/1.1&1]

이것은 n / v 섹션을 다음으로 바꿉니다.

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)+(parseInt("010")<10?(1+1+1+1):0)]

Firefox의 경우 4를 추가하기 위해 parseInt의 차이 (익명으로 Firefox는 0으로 시작하는 숫자를 8 진수로 구문 분석하지만 Chrome은 그렇지 않습니다)를 이용하여 두 경우 모두 'native'에서 'v'를 얻습니다 (다른 'v를 찾을 수 없음 ': P).
parseInt가 약간 벗어난 것처럼 보이지만 지금은 내가 할 수있는 최선입니다.


1
문제는Does anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?
Ian

감사. 이제 저는 브라우저 간 방법을 알아 내려고 노력하고 있습니다 ... 'V'는 놀랍게도 드문 편지입니다 ....
Peter C

@Ian-그렇다면 아마도 [(1 ^ 11 << 1) + 1 + 1 + 1 + 1]은 그렇게 할 것입니까?
enhzflep

@ JanDvorak-현재 FF가 없습니다. 무엇을 평가합니까? 내가 물어볼 정도로 뻔뻔 스러울 수도있다.
enhzflep

@enhzflep 죄송합니다. "Chrome에서는 작동하지 않습니다."
John Dvorak

4

를 들어 일반 문자 케이스는 큰 문제가 아닌 경우 사용 사례, 나는 조금 속이하는 경향 될 수 있습니다.

숫자 0 .. 25를 문자로 바꾸는 함수 "c"를 작성하십시오.

c=function(v){for(var i in window){for(var ci in i){if(parseInt(i[ci],(10+11+11)+(1<<1)+(1<<1))==(v+10)){return i[ci]}}}};

성능상의 이유로 원하는 경우 편지를 미리 캐시하십시오.

l=[];for(var i=0; i<(11+11)+(1<<1)+(1<<1);i++){l[i]=c(i);}

Chrome 콘솔에서 결과 배열은 다음과 같습니다.

> l;
["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "K", "l", "m", "n", "o", "p", "q", "r", "S", "t", "u", "v", "w", "x", "y", "Z"]

그래서 ... 당신의 v 는입니다 l[10+10+1].

또는 다음과 같은 일반적인 솔루션 :

p=(function(){10%11}+[])[1+11+(1<<1)]; // "%"
u=(function(){club=1}+[])[1+11+(1<<1)]; // "u"
vc=p+u+(0+[])+(0+[])+((111>>1)+11+10+[]); // "%u0076"
unescape(vc);

또는이 특정 문제의 경우 아마도 다음과 같습니다.

(function(){v=1}+[])[10+(1<<1)]; // "v"

3

이것은 Chrome에서 av를 제공합니다.

Object.getOwnPropertyNames(Object)[17][3];

그리고 이것은 Firefox에서 수행합니다.

Object.getOwnPropertyNames(Object)[9][3]

그들은 모두 그것을 꺼내서 Object.prototype.preventExtensions(), 아마도 그 방법을 참조하는 브라우저 간 방법을 찾을 수 있습니다. (초보자의 Object.Prototype에서 유일하게 17 자 이름입니다.)

더 혼란 스 러운 버전을 작성하고 자신을 위해 모든 크레딧을 얻으십시오. 나는 시간이 없습니다.)


2

크롬에서 표현식은로 ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])평가되고 "function test() { [native code] }", [1^11<<1]평가는 23으로 평가됩니다 (비트 연산자는 변수가 32 비트로 잘 리도록합니다)


문제는Does anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?
Ian
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.