Jak odzyskać z Internetu DDOS

17

Internet zawiódł. Ataki DDoS są teraz powszechne i powszechne. Od Ciebie zależy, czy przejmiesz kontrolę i naprawisz internet.

Każdy bot będzie kontrolował 20 węzłów w tej sieci. Każdy węzeł jest aktywny lub bezpieczny , ma właściciela i ma siłę, która zaczyna się od 2. Każdy aktywny węzeł jest połączony ze wszystkimi innymi aktywnymi węzłami.

W każdej turze otrzymasz listę wszystkich aktywnych węzłów z ich siłą. Dla każdego z aktywnych aktywnych węzłów:

  1. Wskaż aktywny węzeł, który chcesz przenieść cały siłę, lub
  2. Zapisz i zwiększ jego siłę

Następnie dodaje się dzieje w kolejności :

  1. Węzeł decydujący się na zapisanie swojej siły zwiększy ją o 1.
  2. Wszystkie węzły decydujące się na przeniesienie swojej siły będą jednocześnie przenosić całą swoją siłę do nowego węzła.
  3. Jeśli węzeł został przeniesiony z węzła wroga, nastąpi atak. Jeśli właściciel wroga zbiorowo przenosi więcej siły niż pierwotny właściciel (i wszyscy inni napastnicy), wówczas ten wróg staje się nowym właścicielem. Siła tego węzła staje się wtedy siłą atakującego. Jeśli jest remis, siła zostanie wybrana losowo.
  4. Wszystkie węzły pozostawione bez siły zostaną uwzględnione bezpieczne i dają 1 punkt właścicielowi.

Po 100 grach na 100 tur wygrywa właściciel z najbezpieczniejszymi węzłami we wszystkich grach. EDYCJA: Zmieniłem go z 2000 na 100 zwojów, ponieważ okazało się, że ostatnie 1900 zwojów były bezużyteczne

IO

Zostanie Ci przekazana lista aktywnych węzłów (za pomocą argumentów wiersza poleceń) w następujący sposób:

F20 F4 E7 E2 E20 F2

F oznacza, że ​​węzeł jest węzłem przyjaznym, oraz E oznacza, że ​​węzeł jest wrogiem.

Dla każdego przyjaznego węzła powinieneś zwrócić akcję (poprzez STDOUT) w następujący sposób:

0,0 1,3 5,0

Powyższe oznaczałoby, że chcesz zwiększyć swoją siłę pierwszego węzła, użyć drugiego węzła do zaatakowania czwartego węzła, a twój ostatni węzeł przeniesie jego siłę do pierwszego węzła (a jeśli nikt go nie zaatakuje, stanie się bezpiecznym węzłem ).

Po powrocie program powinien zostać zamknięty.

Tablica wyników

akumulator uzyskał 3240 punktów

z klasą zdobył 2370 punktów

głupi otrzymał 2262 punktów

random_bot zdobył 1603 punktów

smarter_random_bot zdobył 1319 punktów

steady_bot zdobył 1097 punktów

Kontroler można znaleźć tutaj: https://github.com/nathanmerrill/NetAttack

Nathan Merrill
źródło
Kontroler jest sprzeczny ze specyfikacją: „Jeśli nieprzyjacielski właściciel zbiorowo przenosi więcej siły niż pierwotny właściciel ...”. Obecnie jest równy lub większy .
randomra
@randomra: w specyfikacji napisano: jeśli istnieje remis w sile, wówczas właściciel zostanie wybrany losowo
Nathan Merrill
@NathanMerrill Zakładałem, że napastnicy remisują.
randomra
Ostatni pozostały węzeł utknął i czeka do końca gry, prawda? Nie ma sposobu, żeby uciekł?
aebabis
@ acbabis jest poprawny, ale faktycznie testuję to i kończę przedwcześnie grę.
Nathan Merrill,

Odpowiedzi:

5

Accumulator, Python

Zacznijmy tą imprezę! Moje zgłoszenie powinno działać zarówno na Python 2, jak i Python 3.

import sys

inputs = [(i, x[0], int(x[1:])) for (i, x) in enumerate(sys.argv[1].split())]

own_nodes = sorted([(s,i) for (i,o,s) in inputs if o == 'F'])
targets = sorted([(s,i) for (i,o,s) in inputs if o == 'E'])

if targets:
    t_copy = targets[:]
    out = ""
    total_str = 0
    attackers = []
    for (s,i) in own_nodes:
        attackers += [i]
        if t_copy:
            total_str += s
            if t_copy[0][0] < total_str - 1:
                j = max([j for j in range(len(t_copy)) if t_copy[j][0] < total_str - 1])
                out += " ".join([str(k) + "," + str(t_copy[j][1]) for k in attackers]) + " "
                attackers = []
                total_str = 0
                t_copy = t_copy[:j] + t_copy[j+1:]
    if attackers:
        if t_copy:
            out += " ".join([str(k) + "," + str(t_copy[0][1]) for k in attackers])
        else:
            out += " ".join([str(k) + "," + str(attackers[0]) for k in attackers])
else:
    out = " ".join([str(i) + "," + str(own_nodes[0][1]) for (s,i) in own_nodes])

print(out.rstrip())
sys.stdout.flush()

Pomysł jest bardzo prosty. Zaczynam wyliczać moje węzły w kolejności rosnącej, utrzymując bieżącą sumę sił. Kiedy suma przekroczy siłę najsłabszego wrogiego węzła (+1 za możliwy wzrost), atakuję ten węzeł i usuwam go z puli, resetuję sumę i kontynuuję. Na koniec, jeśli najsilniejsze węzły nie będą w stanie znaleźć nikogo do ataku, zdobędą więcej siły.

EDYCJA: Akumulator jest teraz trochę mądrzejszy. Zamiast zawsze atakować najsłabszy węzeł wroga, kumuluje siłę, aż będzie w stanie to zrobić, a następnie atakuje najsilniejszym wolnym węzłem, jaki może z tą siłą. Ponadto, jeśli na końcu pozostaną wrogowie, wszelkie nieprzydzielone węzły zaatakują najsłabszego pozostałego wroga, na wypadek, gdyby zdecydował się przenieść swoją siłę.

Zgarb
źródło
4

Classy, ​​Python3

import random, sys
f,e,p=[],[],[]
for si,s in enumerate(sys.argv[1].split()):
    if s[0]=='F': f+=[(int(s[1:]),si)]
    else: e+=[(int(s[1:]),si)]
f=sorted(f,key=lambda t:t[0]);r=4
f1,f2,f3=f[:len(f)//r],f[len(f)//r:len(f)//r*2],f[len(f)//r*2:]
for fa in f3:
    ea=[t for t in e if t[0]<fa[0]]
    p+=[(fa[1],random.choice(ea)[1])] if ea else [(fa[1],fa[1])]
for fd,fs in zip(f1,reversed(f2)):
    p+=[(fs[1],fd[1])]
    p+=[(fd[1],fd[1])]
if len(e)==0: p=[(fe[1],0) for fe in f]
for t in p: print(t[0],',',t[1],' ',sep='',end='')
sys.stdout.flush()

Bot dzieli własne węzły na 3 kategorie w oparciu o siłę, a każdy węzeł działa zgodnie ze swoją kategorią.

  • Każdy silny węzeł atakuje losowy węzeł wroga, który może pokonać.
  • Każdy środkowy węzeł obsługuje słabą parę węzłów.
  • Każdy słaby węzeł obsługuje się.

Wynik przeciwko Accumulatorowi i dwóm przykładowym botom:

smarter_random_bot got 1301 points
random_bot got 1841 points
Accumulator got 2178 points
Classy got 2580 points
randomra
źródło
2

Dumbot, Nodejs

var input = process.argv.splice(2);
var regexp = new RegExp(" ", "gm");
input = String(input).split(regexp);
var nodes = [];
var targets = [];
for(var i = 0; i < input.length; i++){
    if(input[i].charAt(0) == "F")
        nodes.push(i);
    else
        targets.push(i);
}
var result = "";
var length = nodes.length;
for(var i = 0; i < length; i++){
    if(targets.length>0)
        result += nodes.shift() + "," + targets.shift() + " ";
    else
        result += nodes.shift() + ",0 ";
}
console.log(result);

Bot zaatakuje bez żadnego myślenia ani strategii. Głównym celem jest zapewnienie wielu bezpiecznych węzłów od samego początku. Pamiętaj, że ten bot tworzy nieskończoną pętlę z akumulatorem.

Trafienie
źródło
2

SteadyBot, Node.js

(new Promise(function(resolve, reject) {
    var input = process.argv[2];
    if(input) {
        resolve(input);
    } else {
        process.stdin.once('data', function(data){
            resolve(data.toString());
        });
    }
})).then(function(input) {
    return input.trim().split(' ');
}).then(function(nodes) {
    var friends = [], enemies = [];
    nodes.forEach(function(value, index) {
        var data = { index: index, strength: parseInt(value.substring(1)) };
        if(value[0] === 'F') {
            friends.push(data);
        } else {
            enemies.push(data);
        }
    });

    function weaknessCompare(a, b) {
        return (a.strength > b.strength) ? -1 : ((a.strength < b.strength) ? 1 : 0);
    }

    friends.sort(weaknessCompare);
    enemies.sort(weaknessCompare);

    if(enemies.length === 0) {
        friends.forEach(function(friend) {
            friend.target = 0;
        });
    } else {
        if(friends.length > 0) {
            var strongest = friends[0];
            for(var i = 0; i < enemies.length; i++) {
                var enemy = enemies[i];
                if(enemy.strength + 1 < strongest.strength) {
                    strongest.target = enemy.index;
                    break;
                }
            };
        }
        if(friends.length > 1) {
            friends[1].target = friends[friends.length - 1].index;
        }
    }

    console.log(friends.map(function(friend) {
        return friend.index + ',' +
                (typeof friend.target === 'number' ? friend.target : friend.index);
    }).join(' '));
});
  • Zakłada, że ​​wrogowie nie wzmocnią dużych węzłów: największy przyjazny węzeł atakuje najsilniejszego wroga, którego może pokonać przy takim założeniu.
  • Zakłada, że ​​najsłabszy cel zostanie zaatakowany: Drugi co do wielkości przyjazny węzeł przesuwa się do najsłabszego przyjaznego węzła w każdej rundzie.
  • Chce dużo darmowej siły: inne węzły czekają.
aebabis
źródło
Nie jestem pewien, dlaczego, ale ten bot nie zwraca poprawnie (wypisuje pusty ciąg). Drugi bot nodejs działa, więc polecam przyjrzeć się temu. Powinienem również wspomnieć, że właśnie zainstalowałem nodejs i chociaż znam javascript, mogę brakować czegoś konkretnego dla nodejs.
Nathan Merrill,
Dzięki za zgłoszenie się. Kiedy to robię node SteadyBot.js F20 F4 E7 E2 E20 F2, działa dla mnie. Czy możesz mi powiedzieć dane wejściowe, dla których nie działa?
aebabis
@NathanMerrill Przepisałem go, aby działał również ze standardowym interfejsem. Mam nadzieję, że to naprawia. cat F20 F4 E7 E2 E20 F2 | node SteadyBot.js
aebabis
@acbabis Dane wejściowe podano jako jeden duży argument.
randomra
@acbabis randomra jest poprawna. Otrzymasz 1 duży argument, listę (chyba że dostaniesz wywołanie tak samo jak C ++, w którym to przypadku otrzymasz 2).
Nathan Merrill,