Esiste un dizionario di caratteri Unicode visibilmente simili per l'elaborazione dello spam?

7

Ho spam che assomiglia a questo:

мy вυddy'ѕ мoм мαĸeѕ $74/нoυr oɴ тнe lαpтop. ѕнe нαѕ вeeɴ lαιd oғғ ғor ѕeveɴ мoɴтнѕ вυт lαѕт мoɴтн нer pαy cнecĸ wαѕ $19420 jυѕт worĸιɴɢ oɴ тнe lαpтop ғor α ғew нoυrѕ. нere'ѕ тнe ѕιтe тo reαd мore something­.c­o­m­

Ovviamente questo sta usando Unicode per evitare il rilevamento di spam. Ci sono ASCII - > Dizionari Unicode che possono aiutare a trovare lettere simili?

Questa è una variazione di questa risposta Overflow dello stack ma specifica dello spam.

    
posta random65537 21.05.2013 - 13:28
fonte

2 risposte

5

Vorrei aggiungere al mio algoritmo di classificazione spam qualcosa che rileva più codifiche nella stessa parola / frase. Ad esempio, lαѕт con un latino l , greco / copto alfa, cirillico dze, cirillico te sembra molto sospetto. Una cosa molto veloce e sporca in Python potrebbe essere fatta usando unicodedata. Questo è

>>> unicode_str = u"""мy вυddy'ѕ мoм мαĸeѕ $74/нoυr oɴ тнe lαpтop. ѕнe нαѕ 
вeeɴ lαιd oғғ ғor ѕeveɴ мoɴтнѕ вυт lαѕт мoɴтн нer pαy cнecĸ wαѕ $19420 jυѕт 
worĸιɴɢ oɴ тнe lαpтop ғor α ғew нoυrѕ. нere'ѕ тнe ѕιтe тo reαd мore something­.c­o­m­"""

>>> import unicodedata
>>> for uc in unicode_str:
        print uc, unicodedata.name(uc).split(' ')[0], unicodedata.category(uc)
м CYRILLIC Ll
y LATIN Ll
  SPACE Zs
в CYRILLIC Ll
υ GREEK Ll
d LATIN Ll
d LATIN Ll
y LATIN Ll
' APOSTROPHE Po
ѕ CYRILLIC Ll
(...)

Dove "Ll significa lettera minuscola" e usiamo solo la prima parte del nome Unicode per le lettere per ottenere la sua categoria. Quindi possiamo fare qualcosa di simile

>>> def count_letter_encodings(unicode_str):
        unicode_block_set = set()
        for uc in unicode_str:
            category = unicodedata.category(uc)
            if category[0] == 'L':
                unicode_block = unicodedata.name(uc).split(' ')[0]
                if unicode_block not in unicode_block_set:
                    unicode_block_set.add(unicode_block)
        return len(unicode_block_set)

>>> map(count_letter_encodings, unicode_str.split(' '))
[2, 3, 2, 3, 3, 1, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 3, 0, 3, 2, 1, 2, 3, 2, 1, 2, 3, 2, 2, 3, 2, 2, 2, 1]

Il fatto che ci siano diverse parole con 3 diverse codifiche di lettere è altamente sospetto (anche due sono sospette). Così come altre cose sospette; ad es., i trattini-soft alternati da un carattere (codepoint 0xad) in .com .

Tirando fuori dal Web alcuni brevi campioni di testo estraneo, scopri che la maggior parte delle volte le parole dovrebbero avere una sola codifica:

>>> greek_text = u'Ελληνας ϰαὶ δὴ ϰαὶ γράμματα'
>>> spanish_text = u'¿Cómo estas? Espero que todo esté bien. Hace bastantes años que estoy'
>>> russian_text = u'Все люди рождаются свободными и равными в своем достоинстве и правах. Они наделены'
>>> for text in (greek_text, spanish_text, russian_text):
        print map(count_letter_encodings, text.split(' '))
[1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]

Ovviamente, dovresti testare accuratamente l'apprendimento automatico in quanto potrebbero esserci circostanze benigne in cui le codifiche sono mescolate, ma questo potrebbe essere utile per il tuo classificatore di spam addestrato su un set di dati di grandi dimensioni.

    
risposta data 21.05.2013 - 16:58
fonte
2

Controllo per l'utilizzo delle codifiche multiple nella stessa parola (o frase). Sarebbe un campanello morto per questo genere di cose.

Altrimenti, qualcosa del genere potrebbe aiutarti - sfortunatamente è solo un tavolo parziale, e dovresti usarlo al contrario. I codici esadecimali sono UTF-8, quindi c3a0 significa U+00E0 qui.

a:  c3a0,c3a1,c3a2,c3a3,c3a4,c3a5,c3a6,c481,c483,c485,
c:  c2a2,c3a7,c487,c489,c48b,c48d
d:  c48f,c491
e:  c3a8,c3a9,c3aa,c3ab,c493,c495,c497,c499,c49b
g:  c49d,c49f,c4a1,c4a3
h:  c4a5,c4a7
i:  c2a1,c3ac,c3ad,c3ae,c3af,c4a9,c4ab,c4ae,c4b0,c4ba
j:  c4b5
k:  c4b7,c4b8
l:  c4ae,c4af,c4ba,c4bc
n:  c3b1,c584,c586,c588,c589,c58b
o:  c3b0,c3b2,c3b3,c3b4,c3b5,c3b6,c3b8,c58d,c58f,c591,c593
p:  c3be
s:  c29a
u:  c2b5,c3b9,c3ba,c3bb,c3bc
x:  c397
y:  c3bd,c3bf
z:  c29e
A:  c380,c381,c382,c383,c384,c385,c386,c480,c482,c484
B:  c39f
C:  c387,c486,c488,c48a,c48c
D:  c390,c48e,c490,
E:  c388,c389,c38a,c38b,c492,c494,c496,c498,c49a,c592
G:  c49c,c49e,c4a0,c4a2
H:  c4a4,c4a6
I:  c38c,c38d,c38e,c38f,c4a8,c4aa,c4ac
J:  c4b4
K:  c4b6
L:  c4b9,c4bb,c4bd,c4bf
N:  c391,c583,c585,c587
O:  c392,c393,c394,c395,c396,c398,c58c,c58e,c590,c592
P:  c39e
R:  c594
r:  c595
S:  c28a
U:  c399,c39a,c39b,c39c,
Y:  c29f,c39d
Z:  c28e

A pensarci bene, probabilmente dovresti aggiungere una lista di caratteri "ignore-me" che possono essere aggiunti a una stringa per renderla diversa con un aspetto simile, ad esempio U + 0082. E ora che ci penso, questo potrebbe essere usato per sconfiggere "al massimo due codifiche in ogni frase". Una parola come "déja vu" può essere usata legittimamente (ricordo di averlo visto da un editor Mac), ma l'accostamento di U+0300 può essere usato per far sembrare "Víágŕa" come qualcos'altro.

Quindi prima tutti i "combinings" devono essere rimossi, quindi alcuni caratteri legittimi devono essere ignorati (ad esempio i puntini di sospensione - i processori di testi lo adoro e ... i vari stili di virgolette). Infine, è possibile contare le codifiche o sostituire i caratteri con i loro sostegni OCR come sopra.

    
risposta data 21.05.2013 - 18:38
fonte

Leggi altre domande sui tag