JavaScript'in yerleşik dizeleri nelerdir?


147

bu soruyu bir soru başlığında özetlemek zordur

GÜNCELLEME Bu sorudan çıkarılan harflere dayalı olarak girişinizden gizlenmiş bir dize oluşturan bir JSFiddle oluşturdum: Buradan erişebilirsiniz , yoksa bir öz daha mı kolay olur?

Kısa bir süre önce bu profilde şuna benzeyen , karmaşık bir JavaScript ile karşılaştım :

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]

Sürprizi mahvettiğim için üzgünüm ama bu değerlendirildiğinde şunu döndürüyor:

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

Parçalanmış haldeyken bunun çalışma yolu, bir dizi mesaj oluşturmak ve bu şekilde harfleri onlardan çıkarmaktır (örnek olarak "I" yi kullanarak):

[]+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"

Oluşturulan diğer dizeler şunları içerir:

({}+[])       -> "[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" ve "[" yerine bir yedek bulmakla ilgileniyordum ve şunu buldum:

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

1'leri ve 0'ları kullanma ruhunda hissettiğim, ancak orijinal kodun daha zarif yönlerinden birini ihlal ediyor ki bu, dizelerle hiçbir ilgisi yokmuş gibi görünüyor. Orijinal gizlenmiş kodla uyumlu bir "v" nin nasıl üretileceği hakkında başka bir fikri olan var mı?

İşte birçok yetenekli JavaScript programcısı bu konuya daha derinlemesine baktıktan sonra bulunan bazı ekstra bilgiler.

Firefox, bu satırdan dolayı "Seni yalnızım" döndürür:

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

[1^11<<1] bundan belirli bir karakteri kırpar:

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

Bunu değerlendiren:

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

Görünüşe göre "V" ye sahip olabiliriz !!!

Chrome, aynı kod şunu döndürdüğü için "Seni seviyorum" u döndürür:

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

Soru, "gerçek bir programlama sorunu" ile sorgulanabilir bağlantı için kapatılmadan önce, @ Supr , @ Cory ve @ alpha123'lere dayanan özet bir çözüm eklemeyi düşündüm , işte:

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

Kodun karmaşıklığı ve ürettiği mesaj göz önüne alındığında, neredeyse JavaScript motorunun onu ne kadar özel hissettirdiğinizi anlatması gibi :)


9
Chrome konsolunda "aşk" yazıyor. i.imgur.com/rVyKMoP.png
bfavaretto

2
Ya harf olmayan harfleri çıkarırsanız function test() { [native code] }, onu normalleştirebilir ve istediğiniz mektubu çıkarabilirsiniz
Jason Sperske

4
Sırayla olmayan standartlar tanımlı dize çıkışı kod oturtmakta Ben bu bir aramıştım ... karartılmış kodunu kullanarak mesaj yazdırmak için yol çok lokalize.

2
@ Ian, doğru. Hayatımda sevdiğim insanlar beni gerçekten önemsiyor olsalardı Chrome'u kullanırlardı :)
Jason Sperske

4
Bunun en iyi yanı, metin editörümün verdiği uyarıdır: "'!' Kullanımının kafa karıştırıcı olması"
Jake Johnson

Yanıtlar:


83

Öncelikle, bu komik pasajla oynadıkları için Jason'a ve tüm katkıda bulunanlara teşekkür etmek istiyorum. Bu kodu 14 Şubat'ta eşime göndermek için sadece eğlence için yazdım :) Dizüstü bilgisayara yalnızca Chrome yüklü olduğu için Firefox ve IE'de nasıl çalıştığını kontrol etme seçeneğim yoktu. Dahası, toString()yerleşik yöntemlerin temsilinin diğer tarayıcılarda farklı görünebileceğini gerçekten beklemiyordum .

Şimdi gerçek soruna geçelim, koda tam olarak bir göz atalım. Evet, "v"buradaki gerçek "sorun" idi. [native code]Herhangi bir yerleşik yöntemden alınabilecek ayrıştırma dizesi dışında bu mektubu almanın başka bir yolunu bulamadım . Kendimi hiçbir dizgem ve 1kullanılanlar dışında sayılarla sınırladığım için, adında yalnızca kullanılabilir karakterler bulunan bazı yöntemlerden yararlanmam gerekti.

Mevcut karakterler başından mevcut anahtar kelimelere ve dize temsiller, yani elde edilebilir vardı NaN, null, undefined, Infinity, true, false, ve "[object Object]". Bazıları kolayca dizelere dönüştürülebilir, örneğin 1/!1+[]verir "Infinity".

Diziler [], nesneler {}, düzenli ifadeler /(?:)/, sayılar 1.1, dizeler için farklı yerleşik yöntemleri analiz ettim "1"ve RegExpadı verilen güzel bir nesne yöntemi keşfettim test(). İsmi mevcut tüm karakterlerden, örneğin "t"ve "e"den trueve "s"den derlenebilir false. Bir dize oluşturdum "test"ve bu yöntemi /-/, bu satırda doğru bir şekilde tanımlanan normal ifade için köşeli parantez gösterimi kullanarak ele aldım :

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

Daha önce tartışıldığı gibi, bu kod parçası Chrome'da şu şekilde değerlendirilir:

function test() { [native code] }

Firefox'ta şu şekilde:

function test() {
    [native code]
}

ve IE'de şu şekilde:

 function test() {     [native code] }  

(ikincisinde , anahtar kelimeden önceki boşluğa özellikle dikkat edin function)

Dolayısıyla, açıkça gördüğünüz gibi, kodum sunulan dizeden 24. karakteri alıyordu, ki bu Chrome'da "v"(planlandığı gibi), ancak maalesef Firefox ve IE'de - "n"ve "["sırasıyla.

Tüm tarayıcılarda aynı çıktıyı yapmak için , diğer cevaplarda gösterilenden farklı bir yaklaşım kullandım . Şimdi değiştirilmiş sürüm şuna benzer:

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]

Ancak okuyucuların ilgisini çekmek için buna bir çözüm sunmayacağım. Dürüst olmak gerekirse, nasıl çalıştığını kolayca anlayacağınıza inanıyorum ... ve hatta bazıları sevdiklerini tarayıcılar arası şekilde şaşırtabilir;)

PS Yine Başka Bir Obfuscator

Jason'ın evrensel bir şaşırtma aracı yaratma fikrinden ilham alarak bir tane daha yazdım. Bunu JSBin'de bulabilirsiniz : http://jsbin.com/amecoq/2 . Sayılar [0-9], küçük latin harfleri [a-z]ve boşluklar içeren herhangi bir metni gizleyebilir . Dize uzunluğu çoğunlukla RAM'inizle sınırlıdır (en azından cevabımın gövdesi başarıyla gizlendi). Çıktı, Chrome, Firefox ve IE tarafından desteklenmektedir.

İpucu: Araç, yukarıda sunulandan farklı bir gizleme yaklaşımı kullanır.


4
"kurucu" ... vay bu harika ve geçerli satır sonlarıyla mükemmel dikdörtgeni tuttunuz. Sen iyisin
Jason Sperske

1
Stil kurallarınıza uygun bir dizi oluşturan bir Obfuscator yarattım
Jason Sperske

@JasonSperske Bu güzel bir numaraydı! Harika iş! Katkıda bulunmaya çalışacağım.
VisioN

26

Sorudaki kısım neden native codekullanılmıyor? Bu 'v', hem Chrome hem de Firefox'ta bir verir :

([]+/-/[(!!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'yi desteklemek için düzenleyin ve bunu üçlü operatör olmadan yapın: Bu, Chrome, IE ve FF'de çalışır. Bir dizi oluşturur ve ==tarayıcıyı belirlemek için kullanır .

[([]+/-/[(!!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)]

Okunabilir:

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

Bu ilginç. Başlangıçta "yerel kod" kelimelerinin Firefox ve Chrome arasına yerleştirilmesinin tahmin edilemez olduğu reddedildi. Bu bunu çözer, ancak IE10'da çalışmaz ("i" döndürür). Yine de bu seçeneğin bazı yeni fikirler
sunup sunmayacağını

Fikir sadece seçmek hem etmektir nve vsadece büyük olanı almak: str[23]>str[27]?str[23]:str[27]. Başka bir deyişle, üçüncül operatör hiledir. IE'yi de destekleyecek şekilde uzatılabilir:([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)]
Supr

1
İlk önce cevabınız geldi (orijinal kodu yaratan kişinin önünde), ancak cevabının mantıklı olarak doğru cevap olarak kabul edilebileceğini hissettim. Hala harika bir iş (ve hak edilmiş bir 13
artı

1
Küçük nitpick: üçüncül operatör, birincil ve ikincilden sonra üçüncü en önemli operatördür. Üç işlenen alan bir operatör üçlüdür.
Eric Lippert

1
@EricLippert, gah, hatta doğru terimi kullandığımdan emin olmak için Google'da araştırdım, ancak yine de yanlış olanı buldum! Teşekkürler, düzeltildi.
2013

8

Bu, alabildiğim kadar yaklaştı, ne yazık ki, şunlara bir çağrı yaparak orijinal gizleme kuralını ihlal ediyor unescape():

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

Sökmek:

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

Diğer fikirler:

  1. Bir şekilde olsun unescape("\x76")
  2. Bir şekilde 118aramadan dönüştürünString.fromCharCode()
  3. Metni, içinde "Geçersiz" kelimesi bulunan bir istisnadan alın

Güncellemeler:

Kod golf oynamaya başladım ve daha kısa hale getirdim, parçaları daha fazla 1s ile değiştirdim , vb.


Bunu da beğendim. Hem sizin hem de @ alpha123'ün görünüşü son derece karmaşık ve orijinal niyeti akıllıca gizlediği için, "doğru" bir cevap seçmede biraz parçalanmış durumdayım.
Jason Sperske

Ve IE10 desteği (mükemmel yanıt için samimi özür @ alpha123 ile) mühürler anlaşma
Jason Sperske

Bunu yerini alabilecek '%'olan (/%/+[[]+1/!1])[1]herhangi tırnak çıkarmadan. Referansı gizlemek için l=unescape;küçük harf kullanarak da ekledim . Bu çok eğlenceliydi :)Lunescape
Jason Sperske

@JasonSperske: Daha da kısa:(/%/+[])[1]
Cᴏʀʏ

1
Veya değişkeninizi adlandırabilirsiniz $1;
Cᴏʀʏ

4

İşte n / v'yi oluşturan kısım:

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

Firefox'ta şu şekilde ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])değerlendirilir:

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

Chrome'dayken

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

1^11<<1 23'e eşittir. Dolayısıyla, Firefox'un fazladan boşluğu nedeniyle, bu "v" ye ulaşmak için yeterli değil, bunun yerine "n" dir.

İşte bu yüzden Function # toString davranışına güvenmemelisiniz. ;)

DÜZENLEME: Sonunda, oldukça karmaşık bir tarayıcılar arası sürüm buldum:

[[]+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]

Bu, n / v bölümünü şununla değiştirir:

([]+/-/[(!!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)]

bu, Firefox'un durumunda 4'ü eklemek için parseInt'teki farklılıklardan yararlanır (görünüşe göre Firefox, 0 ile başlayan sayıları sekizlik olarak ayrıştırır, Chrome yapmaz), böylece her iki durumda da "yerel" den "v" alır (başka bir "v" bulamıyorum) ': P).
Ayrıştırma biraz yerinde görünmüyor, ancak şimdilik yapabileceğimin en iyisi bu.


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

Teşekkürler. Şimdi bunu yapmak için bir çapraz tarayıcı şekilde dışarı şekil çalışıyorum ... 'V' şaşırtıcı derecede nadir mektup .... olduğunu
Peter C

@Ian - peki o zaman muhtemelen, [(1 ^ 11 << 1) + 1 + 1 + 1 + 1] yapardı?
Enhzflep

@JanDvorak - Şu anda FF'im ​​yok. Ne değerlendiriyor? Eğer soracak kadar küstah olabilirsem, yani.
Enhzflep

@enhzflep üzgünüm, "diğer yandan bu Chrome'da işe yaramazdı" demek istemiştim
John Dvorak 13

4

İçin genel karakteri muhafaza büyük bir sorun teşkil etmiyorsa kullanım örneği, ben biraz hile meyilli olabilir.

0 .. 25 sayısını bir karaktere dönüştüren "c" işlevini oluşturun.

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]}}}};

Performans nedenleriyle, isterseniz harfleri önbelleğe alın.

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

Chrome konsolunda, ortaya çıkan dizi şu şekilde görünür:

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

Yani ... v'niz olabilir l[10+10+1].

Alternatif olarak, bunun gibi genel bir çözüm:

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

Veya bu özel problem için belki sadece:

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

3

Bu, Chrome'da av değerini verir:

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

Ve bunu Firefox'ta yapıyor:

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

İkisi de onu çıkarır Object.prototype.preventExtensions(), bu yüzden muhtemelen bu yönteme başvurmak için çapraz tarayıcı bir yol bulabilirsiniz. (Yeni başlayanlar için Object.Prototype'daki 17 karakterlik tek addır.)

Bunun daha karmaşık bir versiyonunu oluşturmaktan çekinmeyin ve tüm övgüyü kendiniz için alın, zamanım kalmadı;)


2

Krom, ekspresyon ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])için değerlendirir "function test() { [native code] }", [1^11<<1]23 değerlendirir (bit operatör değişken 32 bit kesildi neden)


SoruDoes anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?
Ian
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.