Flag finder

Bài cổ quá rồi nên mình không nhớ web đấy có gì, đại loại là nó chưa một file script.js mà mình thấy sú xong tải về
Script.js
const fullInput = document.getElementById('fullInput');
const find = document.getElementById('find');
const result = document.getElementById('result');
const len = 1919;
const theFlag = /^(?=(?=(?:.{91}\..{9})*(?:.{91}#.{9}){4}(?:.{91}\..{9})+(?:.{91}#.{9}){5}(?:.{91}\..{9})+(?:.{91}#.{9}){4}(?:.{91}\..{9})*)(?=(?:.{52}\..{48}){19})(?=(?:.{61}\..{39})*(?:.{61}#.{39}){4}(?:.{61}\..{39})+(?:.{61}#.{39})(?:.{61}\..{39})+(?:.{61}#.{39})(?:.{61}\..{39})+(?:.{61}#.{39})(?:.{61}\..{39})+(?:.{61}#.{39}){4}(?:.{61}\..{39})*)(?=(?:.{11}\..{89})*(?:.{11}#.{89})(?:.{11}\..{89})+(?:.{11}#.{89})(?:.{11}\..{89})+(?:.{11}#.{89}){10}(?:.{11}\..{89})*)(?=(?:\..{100}){19})(?=(?:.{56}\..{44}){19})(?=(?:.{40}\..{60}){19})(?=(?:.{26}\..{74})*(?:.{26}#.{74}){2}(?:.{26}\..{74})+(?:.{26}#.{74})(?:.{26}\..{74})+(?:.{26}#.{74})(?:.{26}\..{74})+(?:.{26}#.{74})(?:.{26}\..{74})*)(?=(?:.{23}\..{77})*(?:.{23}#.{77})(?:.{23}\..{77})+(?:.{23}#.{77})(?:.{23}\..{77})+(?:.{23}#.{77})(?:.{23}\..{77})+(?:.{23}#.{77})(?:.{23}\..{77})+(?:.{23}#.{77}){3}(?:.{23}\..{77})*)(?=(?:.{42}\..{58})*(?:.{42}#.{58})(?:.{42}\..{58})+(?:.{42}#.{58})(?:.{42}\..{58})+(?:.{42}#.{58})(?:.{42}\..{58})+(?:.{42}#.{58})(?:.{42}\..{58})+(?:.{42}#.{58})(?:.{42}\..{58})*)(?=(?:.{31}\..{69})*(?:.{31}#.{69}){3}(?:.{31}\..{69})+(?:.{31}#.{69}){2}(?:.{31}\..{69})+(?:.{31}#.{69}){5}(?:.{31}\..{69})*)(?=(?:.{79}\..{21})*(?:.{79}#.{21}){5}(?:.{79}\..{21})+(?:.{79}#.{21})(?:.{79}\..{21})+(?:.{79}#.{21})(?:.{79}\..{21})+(?:.{79}#.{21}){3}(?:.{79}\..{21})*)(?=(?:.{44}\..{56}){19})(?=(?:.{65}\..{35})*(?:.{65}#.{35}){3}(?:.{65}\..{35})+(?:.{65}#.{35}){4}(?:.{65}\..{35})+(?:.{65}#.{35})(?:.{65}\..{35})+(?:.{65}#.{35})(?:.{65}\..{35})+(?:.{65}#.{35})(?:.{65}\..{35})*)(?=(?:.{30}\..{70})*(?:.{30}#.{70})(?:.{30}\..{70})+(?:.{30}#.{70})(?:.{30}\..{70})+(?:.{30}#.{70})(?:.{30}\..{70})*)(?=(?:.{38}\..{62})*(?:.{38}#.{62})(?:.{38}\..{62})+(?:.{38}#.{62})(?:.{38}\..{62})+(?:.{38}#.{62})(?:.{38}\..{62})+(?:.{38}#.{62})(?:.{38}\..{62})+(?:.{38}#.{62})(?:.{38}\..{62})+(?:.{38}#.{62})(?:.{38}\..{62})+(?:.{38}#.{62})(?:.{38}\..{62})*)(?=(?:.{37}\..{63})*(?:.{37}#.{63})(?:.{37}\..{63})+(?:.{37}#.{63}){3}(?:.{37}\..{63})+(?:.{37}#.{63})(?:.{37}\..{63})+(?:.{37}#.{63})(?:.{37}\..{63})*)(?=(?:.{27}\..{73})*(?:.{27}#.{73}){5}(?:.{27}\..{73})+(?:.{27}#.{73})(?:.{27}\..{73})+(?:.{27}#.{73})(?:.{27}\..{73})+(?:.{27}#.{73}){2}(?:.{27}\..{73})*)(?=(?:.{63}\..{37})*(?:.{63}#.{37}){5}(?:.{63}\..{37})+(?:.{63}#.{37}){5}(?:.{63}\..{37})+(?:.{63}#.{37})(?:.{63}\..{37})+(?:.{63}#.{37}){3}(?:.{63}\..{37})*)(?=(?:.{68}\..{32}){19})(?=(?:.{33}\..{67})*(?:.{33}#.{67}){3}(?:.{33}\..{67})+(?:.{33}#.{67}){4}(?:.{33}\..{67})+(?:.{33}#.{67}){4}(?:.{33}\..{67})*)(?=(?:.{53}\..{47})*(?:.{53}#.{47})(?:.{53}\..{47})+(?:.{53}#.{47})(?:.{53}\..{47})+(?:.{53}#.{47}){4}(?:.{53}\..{47})*)(?=(?:.{92}\..{8}){19})(?=(?:.{98}\..{2})*(?:.{98}#.{2})(?:.{98}\..{2})+(?:.{98}#.{2})(?:.{98}\..{2})+(?:.{98}#.{2})(?:.{98}\..{2})+(?:.{98}#.{2})(?:.{98}\..{2})+(?:.{98}#.{2}){2}(?:.{98}\..{2})+(?:.{98}#.{2}){2}(?:.{98}\..{2})*)(?=(?:.{29}\..{71})*(?:.{29}#.{71}){5}(?:.{29}\..{71})+(?:.{29}#.{71}){4}(?:.{29}\..{71})+(?:.{29}#.{71}){3}(?:.{29}\..{71})*)(?=(?:.{100}\.){19})(?=(?:.{58}\..{42})*(?:.{58}#.{42})(?:.{58}\..{42})+(?:.{58}#.{42})(?:.{58}\..{42})+(?:.{58}#.{42})(?:.{58}\..{42})+(?:.{58}#.{42})(?:.{58}\..{42})+(?:.{58}#.{42})(?:.{58}\..{42})+(?:.{58}#.{42})(?:.{58}\..{42})*)(?=(?:.{66}\..{34})*(?:.{66}#.{34})(?:.{66}\..{34})+(?:.{66}#.{34})(?:.{66}\..{34})+(?:.{66}#.{34})(?:.{66}\..{34})+(?:.{66}#.{34})(?:.{66}\..{34})+(?:.{66}#.{34})(?:.{66}\..{34})+(?:.{66}#.{34})(?:.{66}\..{34})+(?:.{66}#.{34})(?:.{66}\..{34})*)(?=(?:.{7}\..{93})*(?:.{7}#.{93}){3}(?:.{7}\..{93})+(?:.{7}#.{93})(?:.{7}\..{93})+(?:.{7}#.{93}){3}(?:.{7}\..{93})*)(?=(?:.{70}\..{30})*(?:.{70}#.{30})(?:.{70}\..{30})+(?:.{70}#.{30})(?:.{70}\..{30})+(?:.{70}#.{30})(?:.{70}\..{30})+(?:.{70}#.{30})(?:.{70}\..{30})+(?:.{70}#.{30}){2}(?:.{70}\..{30})*)(?=(?:.{80}\..{20}){19})(?=(?:.{25}\..{75})*(?:.{25}#.{75}){5}(?:.{25}\..{75})+(?:.{25}#.{75}){2}(?:.{25}\..{75})+(?:.{25}#.{75}){4}(?:.{25}\..{75})*)(?=(?:.{85}\..{15})*(?:.{85}#.{15})(?:.{85}\..{15})+(?:.{85}#.{15}){4}(?:.{85}\..{15})+(?:.{85}#.{15}){3}(?:.{85}\..{15})*)(?=(?:.{54}\..{46})*(?:.{54}#.{46})(?:.{54}\..{46})+(?:.{54}#.{46})(?:.{54}\..{46})+(?:.{54}#.{46})(?:.{54}\..{46})*)(?=(?:.{60}\..{40}){19})(?=(?:.{87}\..{13})*(?:.{87}#.{13})(?:.{87}\..{13})+(?:.{87}#.{13}){3}(?:.{87}\..{13})+(?:.{87}#.{13}){5}(?:.{87}\..{13})*)(?=(?:.{57}\..{43})*(?:.{57}#.{43}){3}(?:.{57}\..{43})+(?:.{57}#.{43})(?:.{57}\..{43})+(?:.{57}#.{43}){4}(?:.{57}\..{43})+(?:.{57}#.{43})(?:.{57}\..{43})+(?:.{57}#.{43})(?:.{57}\..{43})+(?:.{57}#.{43})(?:.{57}\..{43})*)(?=(?:.{20}\..{80}){19})(?=(?:.{96}\..{4}){19})(?=(?:.{17}\..{83})*(?:.{17}#.{83})(?:.{17}\..{83})+(?:.{17}#.{83}){3}(?:.{17}\..{83})+(?:.{17}#.{83}){4}(?:.{17}\..{83})*)(?=(?:.{46}\..{54})*(?:.{46}#.{54})(?:.{46}\..{54})+(?:.{46}#.{54})(?:.{46}\..{54})+(?:.{46}#.{54})(?:.{46}\..{54})+(?:.{46}#.{54})(?:.{46}\..{54})*)(?=(?:.{28}\..{72}){19})(?=(?:.{8}\..{92}){19})(?=(?:.{67}\..{33})*(?:.{67}#.{33}){4}(?:.{67}\..{33})+(?:.{67}#.{33})(?:.{67}\..{33})+(?:.{67}#.{33}){3}(?:.{67}\..{33})+(?:.{67}#.{33}){5}(?:.{67}\..{33})*)(?=(?:.{73}\..{27})*(?:.{73}#.{27}){4}(?:.{73}\..{27})+(?:.{73}#.{27})(?:.{73}\..{27})+(?:.{73}#.{27})(?:.{73}\..{27})+(?:.{73}#.{27}){4}(?:.{73}\..{27})*)(?=(?:.{16}\..{84}){19})(?=(?:.{94}\..{6})*(?:.{94}#.{6})(?:.{94}\..{6})+(?:.{94}#.{6})(?:.{94}\..{6})+(?:.{94}#.{6}){3}(?:.{94}\..{6})+(?:.{94}#.{6})(?:.{94}\..{6})*)(?=(?:.{2}\..{98})*(?:.{2}#.{98}){5}(?:.{2}\..{98})+(?:.{2}#.{98})(?:.{2}\..{98})+(?:.{2}#.{98})(?:.{2}\..{98})*)(?=(?:.{21}\..{79})*(?:.{21}#.{79}){3}(?:.{21}\..{79})+(?:.{21}#.{79})(?:.{21}\..{79})+(?:.{21}#.{79}){4}(?:.{21}\..{79})*)(?=(?:.{81}\..{19})*(?:.{81}#.{19})(?:.{81}\..{19})+(?:.{81}#.{19}){3}(?:.{81}\..{19})+(?:.{81}#.{19}){4}(?:.{81}\..{19})*)(?=(?:.{49}\..{51})*(?:.{49}#.{51}){4}(?:.{49}\..{51})+(?:.{49}#.{51}){3}(?:.{49}\..{51})+(?:.{49}#.{51})(?:.{49}\..{51})*)(?=(?:.{84}\..{16}){19})(?=(?:.{77}\..{23})*(?:.{77}#.{23})(?:.{77}\..{23})+(?:.{77}#.{23})(?:.{77}\..{23})+(?:.{77}#.{23})(?:.{77}\..{23})+(?:.{77}#.{23})(?:.{77}\..{23})+(?:.{77}#.{23}){4}(?:.{77}\..{23})*)(?=(?:.{62}\..{38})*(?:.{62}#.{38})(?:.{62}\..{38})+(?:.{62}#.{38})(?:.{62}\..{38})+(?:.{62}#.{38})(?:.{62}\..{38})+(?:.{62}#.{38})(?:.{62}\..{38})+(?:.{62}#.{38})(?:.{62}\..{38})+(?:.{62}#.{38})(?:.{62}\..{38})+(?:.{62}#.{38})(?:.{62}\..{38})+(?:.{62}#.{38})(?:.{62}\..{38})*)(?=(?:.{5}\..{95})*(?:.{5}#.{95})(?:.{5}\..{95})+(?:.{5}#.{95}){2}(?:.{5}\..{95})+(?:.{5}#.{95})(?:.{5}\..{95})+(?:.{5}#.{95}){4}(?:.{5}\..{95})*)(?=(?:.{90}\..{10})*(?:.{90}#.{10}){3}(?:.{90}\..{10})+(?:.{90}#.{10})(?:.{90}\..{10})+(?:.{90}#.{10})(?:.{90}\..{10})+(?:.{90}#.{10}){3}(?:.{90}\..{10})*)(?=(?:.{76}\..{24}){19})(?=(?:.{47}\..{53})*(?:.{47}#.{53}){5}(?:.{47}\..{53})+(?:.{47}#.{53})(?:.{47}\..{53})+(?:.{47}#.{53}){5}(?:.{47}\..{53})*)(?=(?:.{74}\..{26})*(?:.{74}#.{26})(?:.{74}\..{26})+(?:.{74}#.{26})(?:.{74}\..{26})+(?:.{74}#.{26})(?:.{74}\..{26})+(?:.{74}#.{26}){2}(?:.{74}\..{26})+(?:.{74}#.{26})(?:.{74}\..{26})+(?:.{74}#.{26})(?:.{74}\..{26})*)(?=(?:.{43}\..{57})*(?:.{43}#.{57})(?:.{43}\..{57})+(?:.{43}#.{57})(?:.{43}\..{57})+(?:.{43}#.{57}){2}(?:.{43}\..{57})+(?:.{43}#.{57})(?:.{43}\..{57})*)(?=(?:.{39}\..{61})*(?:.{39}#.{61}){5}(?:.{39}\..{61})+(?:.{39}#.{61})(?:.{39}\..{61})+(?:.{39}#.{61}){2}(?:.{39}\..{61})+(?:.{39}#.{61}){2}(?:.{39}\..{61})*)(?=(?:.{32}\..{68}){19})(?=(?:.{86}\..{14})*(?:.{86}#.{14})(?:.{86}\..{14})+(?:.{86}#.{14})(?:.{86}\..{14})+(?:.{86}#.{14})(?:.{86}\..{14})*)(?=(?:.{55}\..{45})*(?:.{55}#.{45})(?:.{55}\..{45})+(?:.{55}#.{45})(?:.{55}\..{45})+(?:.{55}#.{45}){2}(?:.{55}\..{45})*)(?=(?:.{14}\..{86})*(?:.{14}#.{86}){5}(?:.{14}\..{86})+(?:.{14}#.{86})(?:.{14}\..{86})+(?:.{14}#.{86})(?:.{14}\..{86})+(?:.{14}#.{86})(?:.{14}\..{86})*)(?=(?:.{89}\..{11})*(?:.{89}#.{11}){4}(?:.{89}\..{11})+(?:.{89}#.{11}){2}(?:.{89}\..{11})+(?:.{89}#.{11}){4}(?:.{89}\..{11})*)(?=(?:.{15}\..{85})*(?:.{15}#.{85})(?:.{15}\..{85})+(?:.{15}#.{85})(?:.{15}\..{85})+(?:.{15}#.{85}){5}(?:.{15}\..{85})+(?:.{15}#.{85}){3}(?:.{15}\..{85})*)(?=(?:.{82}\..{18})*(?:.{82}#.{18})(?:.{82}\..{18})+(?:.{82}#.{18})(?:.{82}\..{18})+(?:.{82}#.{18})(?:.{82}\..{18})*)(?=(?:.{45}\..{55})*(?:.{45}#.{55}){2}(?:.{45}\..{55})+(?:.{45}#.{55})(?:.{45}\..{55})+(?:.{45}#.{55}){3}(?:.{45}\..{55})*)(?=(?:.{83}\..{17})*(?:.{83}#.{17}){5}(?:.{83}\..{17})+(?:.{83}#.{17}){5}(?:.{83}\..{17})+(?:.{83}#.{17}){2}(?:.{83}\..{17})*)(?=(?:.{13}\..{87})*(?:.{13}#.{87})(?:.{13}\..{87})+(?:.{13}#.{87}){4}(?:.{13}\..{87})+(?:.{13}#.{87}){4}(?:.{13}\..{87})*)(?=(?:.{71}\..{29})*(?:.{71}#.{29})(?:.{71}\..{29})+(?:.{71}#.{29}){5}(?:.{71}\..{29})+(?:.{71}#.{29})(?:.{71}\..{29})+(?:.{71}#.{29})(?:.{71}\..{29})*)(?=(?:.{19}\..{81})*(?:.{19}#.{81})(?:.{19}\..{81})+(?:.{19}#.{81})(?:.{19}\..{81})+(?:.{19}#.{81}){4}(?:.{19}\..{81})+(?:.{19}#.{81}){5}(?:.{19}\..{81})*)(?=(?:.{6}\..{94})*(?:.{6}#.{94}){2}(?:.{6}\..{94})+(?:.{6}#.{94})(?:.{6}\..{94})+(?:.{6}#.{94})(?:.{6}\..{94})+(?:.{6}#.{94})(?:.{6}\..{94})*)(?=(?:.{88}\..{12}){19})(?=(?:.{93}\..{7})*(?:.{93}#.{7}){5}(?:.{93}\..{7})+(?:.{93}#.{7})(?:.{93}\..{7})*)(?=(?:.{22}\..{78})*(?:.{22}#.{78}){2}(?:.{22}\..{78})+(?:.{22}#.{78}){2}(?:.{22}\..{78})+(?:.{22}#.{78})(?:.{22}\..{78})+(?:.{22}#.{78})(?:.{22}\..{78})+(?:.{22}#.{78})(?:.{22}\..{78})+(?:.{22}#.{78})(?:.{22}\..{78})*)(?=(?:.{18}\..{82})*(?:.{18}#.{82}){5}(?:.{18}\..{82})+(?:.{18}#.{82})(?:.{18}\..{82})+(?:.{18}#.{82})(?:.{18}\..{82})+(?:.{18}#.{82})(?:.{18}\..{82})*)(?=(?:.{34}\..{66})*(?:.{34}#.{66})(?:.{34}\..{66})+(?:.{34}#.{66})(?:.{34}\..{66})+(?:.{34}#.{66})(?:.{34}\..{66})+(?:.{34}#.{66}){3}(?:.{34}\..{66})*)(?=(?:.{24}\..{76}){19})(?=(?:.{4}\..{96}){19})(?=(?:.{36}\..{64}){19})(?=(?:.{3}\..{97})*(?:.{3}#.{97})(?:.{3}\..{97})+(?:.{3}#.{97}){3}(?:.{3}\..{97})+(?:.{3}#.{97})(?:.{3}\..{97})*)(?=(?:.{97}\..{3})*(?:.{97}#.{3})(?:.{97}\..{3})+(?:.{97}#.{3})(?:.{97}\..{3})+(?:.{97}#.{3})(?:.{97}\..{3})+(?:.{97}#.{3}){3}(?:.{97}\..{3})+(?:.{97}#.{3})(?:.{97}\..{3})+(?:.{97}#.{3})(?:.{97}\..{3})*)(?=(?:.{95}\..{5})*(?:.{95}#.{5}){3}(?:.{95}\..{5})+(?:.{95}#.{5})(?:.{95}\..{5})*)(?=(?:.\..{99})*(?:.#.{99})(?:.\..{99})+(?:.#.{99})(?:.\..{99})+(?:.#.{99}){4}(?:.\..{99})+(?:.#.{99})(?:.\..{99})*)(?=(?:.{48}\..{52}){19})(?=(?:.{12}\..{88}){19})(?=(?:.{75}\..{25})*(?:.{75}#.{25})(?:.{75}\..{25})+(?:.{75}#.{25}){3}(?:.{75}\..{25})+(?:.{75}#.{25})(?:.{75}\..{25})+(?:.{75}#.{25})(?:.{75}\..{25})+(?:.{75}#.{25}){5}(?:.{75}\..{25})*)(?=(?:.{59}\..{41})*(?:.{59}#.{41}){5}(?:.{59}\..{41})+(?:.{59}#.{41}){2}(?:.{59}\..{41})+(?:.{59}#.{41}){5}(?:.{59}\..{41})*)(?=(?:.{69}\..{31})*(?:.{69}#.{31})(?:.{69}\..{31})+(?:.{69}#.{31})(?:.{69}\..{31})+(?:.{69}#.{31})(?:.{69}\..{31})+(?:.{69}#.{31})(?:.{69}\..{31})+(?:.{69}#.{31})(?:.{69}\..{31})+(?:.{69}#.{31})(?:.{69}\..{31})*)(?=(?:.{51}\..{49})*(?:.{51}#.{49}){5}(?:.{51}\..{49})+(?:.{51}#.{49}){5}(?:.{51}\..{49})+(?:.{51}#.{49})(?:.{51}\..{49})*)(?=(?:.{72}\..{28}){19})(?=(?:.{50}\..{50})*(?:.{50}#.{50})(?:.{50}\..{50})+(?:.{50}#.{50})(?:.{50}\..{50})+(?:.{50}#.{50})(?:.{50}\..{50})+(?:.{50}#.{50})(?:.{50}\..{50})*)(?=(?:.{78}\..{22})*(?:.{78}#.{22})(?:.{78}\..{22})+(?:.{78}#.{22})(?:.{78}\..{22})+(?:.{78}#.{22})(?:.{78}\..{22})+(?:.{78}#.{22})(?:.{78}\..{22})+(?:.{78}#.{22})(?:.{78}\..{22})+(?:.{78}#.{22})(?:.{78}\..{22})+(?:.{78}#.{22})(?:.{78}\..{22})*)(?=(?:.{10}\..{90})*(?:.{10}#.{90})(?:.{10}\..{90})+(?:.{10}#.{90})(?:.{10}\..{90})+(?:.{10}#.{90})(?:.{10}\..{90})+(?:.{10}#.{90}){2}(?:.{10}\..{90})+(?:.{10}#.{90})(?:.{10}\..{90})*)(?=(?:.{99}\..)*(?:.{99}#.){5}(?:.{99}\..)+(?:.{99}#.){5}(?:.{99}\..)+(?:.{99}#.){3}(?:.{99}\..)*)(?=(?:.{35}\..{65})*(?:.{35}#.{65}){5}(?:.{35}\..{65})+(?:.{35}#.{65}){5}(?:.{35}\..{65})+(?:.{35}#.{65}){4}(?:.{35}\..{65})*)(?=(?:.{41}\..{59})*(?:.{41}#.{59})(?:.{41}\..{59})+(?:.{41}#.{59}){3}(?:.{41}\..{59})+(?:.{41}#.{59})(?:.{41}\..{59})+(?:.{41}#.{59})(?:.{41}\..{59})*)(?=(?:.{9}\..{91})*(?:.{9}#.{91}){2}(?:.{9}\..{91})+(?:.{9}#.{91}){3}(?:.{9}\..{91})+(?:.{9}#.{91})(?:.{9}\..{91})+(?:.{9}#.{91}){4}(?:.{9}\..{91})*)(?=(?:.{64}\..{36}){19}))(?=^.{1919}$)(\.*)(?<=.{101})(?<!.{102})(\.*#{2}\.+#\.+#{2}\.+#{2}\.+#\.+#\.+#\.+#\.+#\.+#{3}\.+#\.+#{2}\.+#{2}\.+#{2}\.+#{3}\.+#{3}\.+#\.+#{3}\.*)(?<=.{202})(?<!.{203})(\.*#\.+#{2}\.+#{2}\.+#{3}\.+#\.+#{2}\.+#\.+#\.+#{2}\.+#\.+#\.+#\.+#{2}\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#{2}\.+#\.*)(?<=.{303})(?<!.{304})(\.*#\.+#{2}\.+#\.+#\.+#{3}\.+#\.+#{3}\.+#\.+#\.+#{3}\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#{3}\.+#{3}\.+#\.+#{3}\.+#\.+#\.+#{3}\.*)(?<=.{404})(?<!.{405})(\.*#\.+#\.+#\.+#\.+#\.+#\.+#{2}\.+#{3}\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#{3}\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#{3}\.+#\.+#\.+#\.*)(?<=.{505})(?<!.{506})(\.*#{3}\.+#{3}\.+#{2}\.+#{2}\.+#\.+#{2}\.+#\.+#\.+#\.+#\.+#\.+#\.+#{3}\.+#{2}\.+#{3}\.+#{3}\.+#\.+#{3}\.+#{2}\.+#{3}\.+#{3}\.+#{3}\.+#\.+#{3}\.+#{3}\.+#\.+#\.+#{3}\.*)(?<=.{606})(?<!.{607})(\.*#{3}\.*)(?<=.{707})(?<!.{708})(\.*#{2}\.+#{2}\.+#{3}\.+#{3}\.+#\.+#\.+#{3}\.+#{2}\.+#{3}\.+#\.+#\.+#\.+#\.+#\.*)(?<=.{808})(?<!.{809})(\.*#{2}\.+#\.+#\.+#\.+#\.+#\.+#\.+#{2}\.+#{3}\.+#\.+#\.+#\.+#\.+#\.+#\.+#{3}\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#{2}\.+#{2}\.+#\.+#\.*)(?<=.{909})(?<!.{910})(\.*#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#{3}\.+#{3}\.+#{3}\.+#\.+#\.+#{3}\.+#{3}\.+#{3}\.+#\.+#{3}\.+#\.+#\.+#\.+#\.+#{3}\.*)(?<=.{1010})(?<!.{1011})(\.*#\.+#\.+#{3}\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.*)(?<=.{1111})(?<!.{1112})(\.*#\.+#\.+#{3}\.+#\.+#{3}\.+#{2}\.+#{3}\.+#{2}\.+#\.+#{3}\.+#{2}\.+#{2}\.+#{3}\.+#\.+#{3}\.+#\.+#{3}\.+#{3}\.+#{3}\.+#\.+#\.+#{3}\.+#\.+#\.+#\.+#{2}\.+#{3}\.+#\.*)(?<=.{1212})(?<!.{1213})(\.*#{3}\.*)(?<=.{1313})(?<!.{1314})(\.*#{2}\.+#{2}\.+#{2}\.+#\.+#\.+#{3}\.+#\.+#\.+#{3}\.+#{2}\.+#{3}\.+#{2}\.+#{2}\.+#\.+#\.+#\.+#{2}\.*)(?<=.{1414})(?<!.{1415})(\.*#{2}\.+#\.+#\.+#{2}\.+#\.+#\.+#\.+#{3}\.+#\.+#\.+#{3}\.+#\.+#\.+#\.+#{3}\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#{3}\.+#\.+#\.+#{3}\.+#\.+#{2}\.*)(?<=.{1515})(?<!.{1516})(\.*#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#{3}\.+#\.+#\.+#{3}\.+#{3}\.+#\.+#{3}\.+#\.+#\.+#{3}\.+#{3}\.+#{3}\.+#\.+#\.+#\.+#{3}\.+#\.+#\.+#{3}\.+#{3}\.+#\.+#\.*)(?<=.{1616})(?<!.{1617})(\.*#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#{3}\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#\.+#{3}\.+#{2}\.*)(?<=.{1717})(?<!.{1718})(\.*#{3}\.+#\.+#\.+#{3}\.+#\.+#\.+#{3}\.+#{3}\.+#\.+#\.+#\.+#\.+#\.+#{3}\.+#\.+#{3}\.+#\.+#{3}\.+#{3}\.+#{3}\.+#\.+#\.+#{3}\.+#{3}\.+#\.+#\.+#\.+#\.+#\.+#{2}\.*)(?<=.{1818})(?<!.{1819})(\.*)(?<=.{1919})(?<!.{1920})$/;
function createInput() {
for (let i = 0; i < len; i++) {
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = `box-${i}`;
checkbox.className = 'grid-box';
fullInput.appendChild(checkbox);
}
}
function match() {
const boxes = document.querySelectorAll('.grid-box');
let input = "";
boxes.forEach(box => {
input += box.checked ? "#" : ".";
});
result.className = 'status';
if (theFlag.test(input)) {
result.textContent = "✅ Flag found!";
result.classList.add('success');
} else {
result.textContent = "⌠Flag not found.";
result.classList.add('error');
}
}
createInput();
find.addEventListener('click', match);
Script này sẽ đơn giản là vẽ hình ra với ký tự . và #
Hàm này nhận những mảnh như:
- (?:.{91}\..{9})
- (?:.{91}#.{9})
- (?:\..{100})
- (?:.{100}\.)
và hiểu chúng là:
“Trong một hàng dài đúng 101 ký tự, ở vị trí cột pre_len thì ký tự phải là . hoặc #.”
Script để vẽ lại hình theo yêu cầu của file js
#!/usr/bin/env python3
import re
import sys
from functools import lru_cache
from PIL import Image
COLS = 101 # from CSS repeat(101,...)
def extract_regex_and_len(js: str):
mlen = re.search(r"const\s+len\s*=\s*(\d+)\s*;", js)
if not mlen:
raise ValueError("Cannot find const len = ...;")
total_len = int(mlen.group(1))
# non-greedy capture between / ... /;
m = re.search(r"const\s+theFlag\s*=\s*/(.*?)/\s*;", js, re.S)
if not m:
raise ValueError("Cannot find const theFlag = /.../;")
regex_src = m.group(1)
return regex_src, total_len
def extract_lookaheads(s: str):
"""
Return ALL lookaheads '(?=...)' including nested ones.
"""
out = []
def find_end(i: int) -> int:
# i points to '(' of '(?='
depth = 0
j = i
while j < len(s):
ch = s[j]
if ch == '\\': # skip escaped char
j += 2
continue
if ch == '(':
depth += 1
elif ch == ')':
depth -= 1
if depth == 0:
return j
j += 1
raise ValueError("Unbalanced parentheses while parsing lookaheads")
def walk(lo: int, hi: int):
i = lo
while i < hi:
if s.startswith("(?=", i):
end = find_end(i)
out.append(s[i:end+1])
# recurse inside the lookahead body
walk(i + 3, end) # content inside '(?=' ... ')'
i = end + 1
else:
i += 1
walk(0, len(s))
return out
def parse_chunk_group(g: str):
"""
Parse chunk like (?:.{91}\..{9}) or (?:\..{100}) or (?:.\..{99}) or (?:.{100}\.)
and same with # in place of \.
Return (col_index, sym) where sym in {'.','#'} if it is exactly one row-chunk of length 101.
"""
if not (g.startswith("(?:") and g.endswith(")")):
return None
inner = g[3:-1]
# prefix: "", "." or ".{n}"
# sym: "\." or "#"
# suffix: "", "." or ".{n}"
m = re.fullmatch(r"(?:(?:\.\{(\d+)\})|(\.))?(\\\.|#)(?:(?:\.\{(\d+)\})|(\.))?", inner)
if not m:
return None
pre_n, pre_dot, sym, suf_n, suf_dot = m.groups()
pre_len = int(pre_n) if pre_n else (1 if pre_dot else 0)
suf_len = int(suf_n) if suf_n else (1 if suf_dot else 0)
if pre_len + 1 + suf_len != COLS:
return None
col = pre_len
sym_char = '.' if sym == r'\.' else '#'
return col, sym_char
def parse_column_constraint(look: str):
"""
Try interpret a lookahead as a single-column vertical nonogram constraint.
Return (col_index, clues_list) or None.
"""
# Extract all (?:...) groups that parse as row-chunks; must all point to same column.
cols = set()
dot_chunk = None
hash_chunk = None
i = 0
while i < len(look):
if look.startswith("(?:", i):
depth = 0
j = i
while j < len(look):
ch = look[j]
if ch == '\\':
j += 2
continue
if ch == '(':
depth += 1
elif ch == ')':
depth -= 1
if depth == 0:
grp = look[i:j+1]
pc = parse_chunk_group(grp)
if pc:
col, sym = pc
cols.add(col)
if sym == '.':
dot_chunk = grp
else:
hash_chunk = grp
i = j + 1
break
j += 1
else:
break
else:
i += 1
if not cols or len(cols) != 1:
return None
col = next(iter(cols))
# Dot-only column constraint → no hash runs
if hash_chunk is None and dot_chunk is not None:
return col, []
if not dot_chunk or not hash_chunk:
return None
# Count hash runs from occurrences of the hash chunk followed by optional {n}
hs = re.escape(hash_chunk)
clues = []
for m in re.finditer(hs + r"(\{(\d+)\})?", look):
n = int(m.group(2)) if m.group(2) else 1
clues.append(n)
return col, clues
def extract_row_clues(regex_src: str, total_len: int, rows: int):
marker = f"(?=^.{{{total_len}}}$)"
if marker not in regex_src:
raise ValueError("Cannot find length marker in regex")
_, suffix = regex_src.split(marker, 1)
# Row 0 is the very first capturing group: (\.*) (or generally: (<no ')'>))
m0 = re.match(r"\(([^)]*)\)", suffix)
if not m0:
raise ValueError("Cannot find leading row-0 group after length marker")
row_patts = [m0.group(1)]
pos = m0.end()
# Rows 1..rows-1 are: (?<=.{k})(?<!.{k+1})(...)
for i in range(1, rows):
k = i * COLS
pat = re.compile(rf"\(\?<=\.\{{{k}\}}\)\(\?<\!\.\{{{k+1}\}}\)\(([^)]*)\)")
m = pat.search(suffix, pos)
if not m:
raise ValueError(f"Cannot find row {i} group at boundary {k}")
row_patts.append(m.group(1))
pos = m.end()
if len(row_patts) != rows:
raise ValueError(f"Expected {rows} row-patterns, got {len(row_patts)}")
row_clues = []
for patt in row_patts:
blocks = []
for t in re.finditer(r"#\{(\d+)\}|#", patt):
blocks.append(int(t.group(1)) if t.group(1) else 1)
row_clues.append(blocks)
return row_clues
def extract_col_clues(regex_src: str, total_len: int, cols: int):
marker = f"(?=^.{{{total_len}}}$)"
prefix, _ = regex_src.split(marker, 1)
looks = extract_lookaheads(prefix)
colmap = {}
for lk in looks:
parsed = parse_column_constraint(lk)
if not parsed:
continue
c, clues = parsed
# Keep the “most informative” one if duplicates show up
if c not in colmap or len(clues) > len(colmap[c]):
colmap[c] = clues
if len(colmap) != cols:
missing = [c for c in range(cols) if c not in colmap]
raise ValueError(f"Missing column constraints for {len(missing)} cols (e.g. {missing[:10]})")
return [colmap[c] for c in range(cols)]
def line_analyze(L, clues, fixed):
"""
fixed: list of -1 (unknown), 0 (dot), 1 (hash)
returns: feasible, forced(list -1/0/1)
"""
k = len(clues)
fixed = list(fixed)
def trans(state, ch):
idx, run_left, must_dot = state
if run_left > 0:
if ch != '#':
return None
if run_left == 1:
new_idx = idx + 1
new_must = (new_idx < k)
return (new_idx, 0, new_must)
return (idx, run_left - 1, False)
else:
if must_dot:
if ch != '.':
return None
return (idx, 0, False)
else:
if ch == '.':
return (idx, 0, False)
if ch == '#':
if idx >= k:
return None
length = clues[idx]
if length == 1:
new_idx = idx + 1
new_must = (new_idx < k)
return (new_idx, 0, new_must)
return (idx, length - 1, False)
return None
start = (0, 0, False)
accept = (k, 0, False)
fwd = [set() for _ in range(L+1)]
fwd[0].add(start)
for pos in range(L):
allowed = []
if fixed[pos] != 1:
allowed.append('.')
if fixed[pos] != 0:
allowed.append('#')
for st in fwd[pos]:
for ch in allowed:
ns = trans(st, ch)
if ns is not None:
fwd[pos+1].add(ns)
if accept not in fwd[L]:
return False, [-1] * L
bwd = [set() for _ in range(L+1)]
bwd[L].add(accept)
for pos in range(L-1, -1, -1):
allowed = []
if fixed[pos] != 1:
allowed.append('.')
if fixed[pos] != 0:
allowed.append('#')
for st in fwd[pos]:
for ch in allowed:
ns = trans(st, ch)
if ns is not None and ns in bwd[pos+1]:
bwd[pos].add(st)
break
can0 = [False] * L
can1 = [False] * L
for pos in range(L):
for st in fwd[pos]:
if st not in bwd[pos]:
continue
if fixed[pos] != 1:
ns = trans(st, '.')
if ns is not None and ns in bwd[pos+1]:
can0[pos] = True
if fixed[pos] != 0:
ns = trans(st, '#')
if ns is not None and ns in bwd[pos+1]:
can1[pos] = True
if can0[pos] and can1[pos]:
break
forced = [-1] * L
for i in range(L):
if can1[i] and not can0[i]:
forced[i] = 1
elif can0[i] and not can1[i]:
forced[i] = 0
return True, forced
def solve_nonogram(row_clues, col_clues):
R = len(row_clues)
C = len(col_clues)
grid = [[-1] * C for _ in range(R)]
def propagate(g):
changed = True
while changed:
changed = False
for r in range(R):
ok, forced = line_analyze(C, row_clues[r], g[r])
if not ok:
return False
for c, v in enumerate(forced):
if v != -1 and g[r][c] != v:
if g[r][c] != -1 and g[r][c] != v:
return False
g[r][c] = v
changed = True
for c in range(C):
col = [g[r][c] for r in range(R)]
ok, forced = line_analyze(R, col_clues[c], col)
if not ok:
return False
for r, v in enumerate(forced):
if v != -1 and g[r][c] != v:
if g[r][c] != -1 and g[r][c] != v:
return False
g[r][c] = v
changed = True
return True
def complete(g):
return all(x != -1 for row in g for x in row)
def pick_unknown(g):
for r in range(R):
for c in range(C):
if g[r][c] == -1:
return r, c
return None
def bt(g):
if not propagate(g):
return None
if complete(g):
return g
r, c = pick_unknown(g)
for v in (1, 0):
ng = [row[:] for row in g]
ng[r][c] = v
sol = bt(ng)
if sol is not None:
return sol
return None
return bt(grid)
def render_ascii(grid):
return "\n".join("".join("#" if v == 1 else "." for v in row) for row in grid)
def render_png(grid, scale=10, outpath="out.png"):
R = len(grid)
C = len(grid[0])
img = Image.new("RGB", (C * scale, R * scale), (255, 255, 255))
px = img.load()
for r in range(R):
for c in range(C):
if grid[r][c] == 1:
for y in range(r*scale, (r+1)*scale):
for x in range(c*scale, (c+1)*scale):
px[x, y] = (0, 0, 0)
img.save(outpath)
def main():
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} script.js")
sys.exit(1)
js = open(sys.argv[1], "r", encoding="utf-8", errors="replace").read()
regex_src, total_len = extract_regex_and_len(js)
rows = total_len // COLS
if rows * COLS != total_len:
raise ValueError(f"len={total_len} not divisible by COLS={COLS}")
row_clues = extract_row_clues(regex_src, total_len, rows)
col_clues = extract_col_clues(regex_src, total_len, COLS)
grid = solve_nonogram(row_clues, col_clues)
if grid is None:
raise RuntimeError("No solution found")
art = render_ascii(grid)
open("out.txt", "w", encoding="utf-8").write(art + "\n")
render_png(grid, scale=10, outpath="out.png")
# Flatten to the exact input string (1919 chars) to auto-fill in browser
flat = "".join("".join("#" if v == 1 else "." for v in row) for row in grid)
open("solution.bin", "w", encoding="utf-8").write(flat)
print("[+] Solved.")
print("[+] Wrote out.txt, out.png, solution.bin")
print("\n[+] Browser autofill snippet (paste in DevTools console):\n")
print("(() => {")
print(" const s = `" + flat + "`;")
print(" for (let i=0;i<s.length;i++) {")
print(" const el = document.getElementById(`box-${i}`);")
print(" if (el) el.checked = (s[i] === '#');")
print(" }")
print(" console.log('filled');")
print("})();\n")
print("[+] Now click “Find flag” and read the text drawn on the grid (that text is the flag).")
if __name__ == "__main__":
main()
Nó sẽ vẽ được một hình như sau

Flag: lactf{Wh47_d0_y0u_637_eh3n_y0u_cr055_4_r363x_4nd_4_n0n06r4m?_4_r3g3x06r4m!}
'WriteUp > RE' 카테고리의 다른 글
| Rev - UofTCTF 2026 (0) | 2026.01.13 |
|---|---|
| Cosmonaut - BuckeyeCTF 2025 (0) | 2025.11.09 |
| Square Cipher - BuckeyeCTF 2025 (0) | 2025.11.09 |
| Python 0bf (0) | 2025.11.02 |
| [RE] Clockwork - EnigmaXplore 3.0 (0) | 2025.10.20 |
