CTF比赛的一道javascript题

今天中午的时候,舍友发来一道javascript题目给我看,要求调用下面的函数,输出“Yay!!”

function test(arr) {
    var random_value = "ac1a39300ce7ee8b6cff8021fd7b0b5caf5bc1c316697bd8f22e00f9fab710d6b8dba23ca80f6d80ca697e7aa26fd5f6";
    var check = "20150303";

    if((arr === null || arr === undefined)) {
        console.log("arr is null or undefined.");
        return;
    }

    if(!arr.hasOwnProperty('length')) {
        console.log("length property is null or undefined.");
        return;
    }

    if(arr.length >= 0) {
        console.log("i think you're not geek. From now on, a GEEK Only!");
        return;
    }

    if(Object.getPrototypeOf(arr) !== Array.prototype) {
        console.log("Oh.... can you give me an array?");
        return;
    }

    var length = check.length;
    for(var i=0;i<length;i++) {
        arr[i] = random_value[Math.floor(Math.random() * random_value.length)];
    }

    for(i=0;i<length;i++) {
        if(arr[i] !== check[i]) {
            console.log("Umm... i think 2015/03/03 is so special day.\nso you must set random value to 20150303 :)");
            return;
        }
    }
    console.log("Yay!!");
}

粗略看了一下题目,尝试了下

var arr=[];
test(arr);//i think you're not geek. From now on, a GEEK Only! 

输出了i think you’re not geek. From now on, a GEEK Only! 赤裸裸地被作者鄙视了呀。可见,在第三个判断if(arr.length >= 0)这里就过不去了。一般来说,数组的length属性都不能小于0的。强制给arr.length赋值会怎么样呢

arr.length=-1;
//Uncaught RangeError: Invalid array length 

果然抛出了错误,看来这个思路不行。换条路走
自己定义一个对象试试吧

var arr={length:-1};
test(arr);//Oh.... can you give me an array? 

第三个判断是过去了,第四个if(Object.getPrototypeOf(arr) !== Array.prototype)没过去呢,要求是数组哦。可是数组的length属性又不能小于0。这下子好像出现了死循环。然后我谷歌了一下Object.getPrototypeOf()
官方定义:The Object.getPrototypeOf() method returns the prototype (i.e. the value of the internal [[Prototype]] property) of the specified object.

var proto = {};
var obj = Object.create(proto);
Object.getPrototypeOf(obj) === proto; // true

简单的说,就是返回对象的prototype属性
于是我就想,那就让arr的prototype指向Array.prototype呀。试试

var arr={length:-1};
arr.prototype=Array.prototype;
test(arr);
//Oh.... can you give me an array? 

还是不行,第四关还是过不了,我自己输出Object.getPrototypeOf(arr)和Array.prototype看看,结果为

Object.getPrototypeOf(arr)
//Object {}
Array.prototype
//[]

用{}这样形式生成的还是object对象,不是数组对象。怎么办,换个思路。于是想到另一种生成对象的方式

var MyArr=function(){
    this.length=-1;
}
MyArr.prototype=Array.prototype;
var arr=new MyArr();
test(arr);//Umm... i think 2015/03/03 is so special day.
//so you must set random value to 20150303 :) 

太棒了,第四关过了,nice。好兴奋,胜利就在眼前。这种方式构造出来的对象,使用的是Array.prototype的原型链。相当于new Array(),但是constructor用的是我们MyArr自己定义的。(这里我的理解解释不知道是不是正确,如果有误,欢迎指出修改)
接下来第五关

var random_value = "ac1a39300ce7ee8b6cff8021fd7b0b5caf5bc1c316697bd8f22e00f9fab710d6b8dba23ca80f6d80ca697e7aa26fd5f6";
var check = "20150303";
var length = check.length;
    for(var i=0;i<length;i++) {
        arr[i] = random_value[Math.floor(Math.random() * random_value.length)];
    }

    for(i=0;i<length;i++) {
        if(arr[i] !== check[i]) {
            console.log("Umm... i think 2015/03/03 is so special day.\nso you must set random value to 20150303 :)");
            return;
        }
    }

出题者要求arr数组的内容是“20150303”。然后函数中又给arr赋值,而且赋的是随机值。我一看,出题者使的一定是个障眼法,让我们去纠结那些随机数怎么搞出”20150303”。我们不能在这里花时间,得换个思路。想了想,有没有一种方法,可以让对象的值不能被修改,这样我们在函数外赋值好后,传入函数中,就不会被修改了。这个思路似乎可行,立马谷歌。
找到了Object.freeze();这个方法。我们来看一下官方定义

概述EDIT
Object.freeze() 方法可以冻结一个对象。冻结对象是指那些不能添加新的属性,不能修改已有属性的值,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性的对象。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。

语法EDIT Object.freeze(obj)

这样问题似乎都解决了,试试

var MyArr=function(){
    this.length=-1;
}
MyArr.prototype=Array.prototype
var arr=new MyArr()
arr[0]='2';
arr[1]='0';
arr[2]='1';
arr[3]='5';
arr[4]='0';
arr[5]='3';
arr[6]='0';
arr[7]='3';
Object.freeze(arr);
test(arr);//Yay!! 

终于,功夫不负有心人,问题解决了。在这个猜测、验证、搜索和思考过程中,得到了很多锻炼。每解决一步都给人成就感。感谢我舍友给我发来这一道题。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值