Files
AI-Red-Teaming-CSCD94/ai-evasion/goodwords-challenge.ipynb
T
2026-07-26 22:53:03 -04:00

5.0 KiB

In [1]:
import os
import requests
import random
import numpy as np
from typing import List, Tuple

# Seed for reproducibility
random.seed(1337)
np.random.seed(1337)

# Get challenge from server
host = "http://154.57.164.78:31757"
ch = requests.get(f"{host}/challenge", timeout=10).json()
base, budget = ch["base_message"], int(ch["max_added_words"])

def predict(host, text):
    r = requests.post(f"{host}/predict", json={"text": text}, timeout=15)
    data = r.json()
    return data["label"], float(data["spam_probability"])

vocab = list(dict.fromkeys([
    # salutations and courtesy
    "hello", "hi", "dear", "please", "thanks", "thankyou", "regards", "sincerely",
    "kind", "wishes", "best", "appreciate", "welcome", "friend", "family",
    # everyday context
    "meeting", "tomorrow", "today", "later", "morning", "night", "home", "work",
    "office", "schedule", "confirm", "call", "reply", "message", "note", "update",
    # positive tone
    "happy", "birthday", "congratulations", "joy", "peace", "smile", "care",
    "support", "help", "good", "great", "wonderful", "awesome", "nice", "cool",
    "fine", "okay",
    # social
    "lunch", "dinner", "coffee", "weekend", "party", "invite", "visit", "enjoy",
    # misc
    "true", "honest", "trust", "safe", "project", "team"
]))

def estimate_word_impacts(
    host: str, base_msg: str, words: List[str]
) -> List[Tuple[str, float]]:
    _, base_prob = predict(host, base_msg)
    impacts: List[Tuple[str, float]] = []
    for w in words:
        augmented = f"{base_msg} {w}"
        _, new_prob = predict(host, augmented)
        impacts.append((w, base_prob - new_prob))
    impacts.sort(key=lambda x: x[1], reverse=True)
    return impacts

def greedy_compose(
    host: str, base_msg: str, top_words: List[str], budget: int, target_label: str
) -> Tuple[str, int, float]:
    augmented = base_msg
    used = 0
    for w in top_words:
        if used >= budget:
            break
        augmented = f"{augmented} {w}"
        used += 1
        label, prob = predict(host, augmented)
        if label == target_label:
            return augmented, used, prob
    label, prob = predict(host, augmented)
    return augmented, used, prob


if __name__ == "__main__":
    print(f"Base message: '{base}'\nBudget: {budget}")

    #Estimate which words help reduce spam probability
    impacts = estimate_word_impacts(host, base, vocab)
    top_words = [w for w, delta in impacts if delta > 0]

    #Try to fix the message using greedy approach
    final_msg, used, final_prob = greedy_compose(host, base, top_words, budget, target_label="ham")
    final_label, _ = predict(host, final_msg)

    print(f"\nFinal message: '{final_msg}'")
    print(f"Words used: {used}")
    print(f"Final classification: {final_label} (spam prob: {final_prob:.4f})")
Base message: 'England v Macedonia - dont miss the goals/team news. Txt ur national team to 87077 eg ENGLAND to 87077 Try:WALES, SCOTLAND 4txt/ú1.20 POBOXox36504W45WQ 16+'
Budget: 25

Final message: 'England v Macedonia - dont miss the goals/team news. Txt ur national team to 87077 eg ENGLAND to 87077 Try:WALES, SCOTLAND 4txt/ú1.20 POBOXox36504W45WQ 16+ later home morning fine nice lunch meeting happy'
Words used: 8
Final classification: ham (spam prob: 0.1077)
In [ ]: