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

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

업데이트이
질문에서 추출한 문자를 기반으로 입력에서 난독 처리 된 문자열을 작성하는 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 엔진이 느끼는 것이 얼마나 특별하다고 말하는 것과 거의 같습니다. 🙂



답변

우선, 저 재미있는 스 니펫을 가지고 놀아 준 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에서 지원됩니다.

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


답변

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)
]


답변

이것은 내가 얻을 수있는 한 가깝습니다. 불행히도 그것은 다음을 호출하여 원래 난독 화의 규칙을 위반합니다 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등의 작업을 수행했습니다.


답변

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가 약간 벗어난 것처럼 보이지만 지금은 내가 할 수있는 최선입니다.


답변

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

숫자 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"


답변

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

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

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

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

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

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


답변

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