Come recuperare da Internet DDOS


17

Internet ha fallito. Gli attacchi DDoS sono ora dilaganti e diffusi. Sta a te prendere il controllo e riparare Internet.

Ogni bot controllerà 20 nodi in questa rete. Ogni nodo è attivo o sicuro , ha un proprietario e ha un punto di forza, che inizia da 2. Ogni nodo attivo è connesso a tutti gli altri nodi attivi.

Ad ogni turno, riceverai un elenco di tutti i nodi attivi con la loro forza. Per ciascuno dei nodi attivi che possiedi, puoi:

  1. Designare un nodo attivo su cui si desidera trasferire l' intera forza o
  2. Salva e aumenta la sua forza

Poi si verifica quanto segue in ordine :

  1. Un nodo che sceglie di salvare la sua forza aumenterà la sua forza di 1.
  2. Tutti i nodi che scelgono di trasferire la propria forza trasferiranno contemporaneamente tutta la loro forza al nuovo nodo.
  3. Se a un nodo è stata trasferita la forza da un nodo nemico, ne conseguirà un attacco. Se un proprietario nemico trasferisce collettivamente più forza del proprietario originale (e di tutti gli altri attaccanti), quel nemico diventa il nuovo proprietario. La forza di quel nodo diventa quindi la forza dell'attaccante. Se c'è un pareggio per la forza, il proprietario verrà scelto a caso.
  4. Tutti i nodi lasciati senza alcun punto di forza verranno considerati sicuri e assegneranno 1 punto al proprietario.

Dopo 100 partite da 100 turni, vince il proprietario con i nodi più sicuri in tutte le partite. EDIT: L'ho cambiato da 2000 a 100 turni, poiché alla fine gli ultimi 1900 giri erano inutili

IO

Verrà passato l'elenco dei nodi attivi (tramite args della riga di comando) come il seguente:

F20 F4 E7 E2 E20 F2

Findica che il nodo è un nodo amico e Eindica che il nodo è nemico.

Per ciascuno dei tuoi nodi amici, dovresti restituire un'azione (tramite STDOUT) come il seguente:

0,0 1,3 5,0

Quanto sopra significherebbe che vuoi aumentare la tua forza del primo nodo, usare il tuo secondo nodo per attaccare il quarto nodo, e il tuo ultimo nodo trasferirà la sua forza nel primo nodo (e se nessuno lo attacca, diventerà un nodo sicuro ).

Dopo il ritorno, il programma dovrebbe essere chiuso.

tabellone segnapunti

l'accumulatore ha ottenuto 3240 punti

di classe ha ottenuto 2370 punti

dumbot ha ottenuto 2262 punti

random_bot ha ottenuto 1603 punti

smarter_random_bot ha ottenuto 1319 punti

steady_bot ha ottenuto 1097 punti

Il controller può essere trovato qui: https://github.com/nathanmerrill/NetAttack


Il controllore contraddice la specifica: "Se un proprietario nemico trasferisce collettivamente più forza del proprietario originale ...". Attualmente è uguale o più .
randomra,

@randomra: nelle specifiche dice: Se c'è un pareggio per la forza, il proprietario verrà scelto a caso
Nathan Merrill

@NathanMerrill Ho ipotizzato che se gli attaccanti pareggiano.
randomra,

L'ultimo nodo rimanente è bloccato in attesa fino alla fine del gioco, giusto? Non c'è modo per lui di scappare?
aebabis

@acbabis è corretto, ma in realtà lo provo e finisco il gioco prematuramente a quel punto.
Nathan Merrill,

Risposte:


5

Accumulatore, Python

Diamo inizio alla festa! La mia presentazione dovrebbe funzionare sia su Python 2 che su 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()

L'idea è davvero semplice. Comincio a enumerare i miei nodi in ordine crescente di forza, mantenendo una somma progressiva dei punti di forza. Quando la somma supera la forza del nodo nemico più debole (+1 per un possibile aumento), attacco quel nodo e lo rimuovo dal pool, resetto la somma e continuo. Alla fine, se i nodi più forti non riescono a trovare nessuno da attaccare, raccoglieranno più forza.

EDIT: l' accumulatore è ora un po 'più intelligente. Invece di attaccare sempre il nodo nemico più debole, accumula la forza fino a quando non potrebbe farlo, e quindi attacca il nodo libero più forte che può con quella forza. Inoltre, se alla fine sono rimasti nemici, tutti i nodi non assegnati attaccheranno il nemico rimasto più debole, nel caso in cui decida di trasferire la sua forza.


4

Elegante, 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()

Il bot suddivide i propri nodi in 3 categorie in base alla forza e ogni nodo agisce in base alla sua categoria.

  • Ogni nodo forte attacca un nodo nemico casuale che può battere.
  • Ogni nodo centrale supporta la sua coppia di nodi deboli.
  • Ogni nodo debole si supporta da solo.

Risultato contro l'accumulatore e i due robot di campionamento:

smarter_random_bot got 1301 points
random_bot got 1841 points
Accumulator got 2178 points
Classy got 2580 points

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

Il bot attaccherà senza alcun pensiero o strategia. L'obiettivo principale è garantire un sacco di nodo sicuro all'inizio. Tieni presente che questo bot crea un ciclo infinito con l'accumulatore.


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(' '));
});
  • Suppone che i nemici non rinforzino nodi grandi: il più grande nodo amico attacca il nemico più forte che può battere sotto questo presupposto.
  • Suppone che il bersaglio più debole verrà attaccato: il secondo nodo amico più grande si sposta sul nodo amico più debole ogni round.
  • Vuole molta forza libera: altri nodi aspettano.

Non sono sicuro del perché, ma questo bot non ritorna correttamente (stampa una stringa vuota). L'altro bot nodejs funziona, quindi ti consiglio di dare un'occhiata. Dovrei anche menzionare che ho appena installato nodejs e mentre conosco javascript, potrei mancare qualcosa di specifico a nodejs.
Nathan Merrill

Grazie per il testa a testa. Quando lo faccio node SteadyBot.js F20 F4 E7 E2 E20 F2, funziona per me. Potresti dirmi l'input per il quale non riesce?
aebabis

@NathanMerrill L'ho riscritto per funzionare anche con Stdin. Spero che lo risolva. cat F20 F4 E7 E2 E20 F2 | node SteadyBot.js
aebabis

@acbabis Input è dato come un grande argomento.
randomra,

@acbabis randomra è corretta. Otterrai 1 grande argomento, l'elenco (a meno che tu non riceva la chiamata come C ++, nel qual caso ne otterrai 2).
Nathan Merrill
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.