Non sono sicuro che sia sulla falsariga che stai cercando (e molto probabilmente hai già capito tutto questo e altro), ma ecco una grossolana formalizzazione e poi alcune riflessioni sull'implementazione. Concettualmente, questo cerca di separare ciò che significa intrecciare diversi valori dal modo in cui i valori intrecciati sono rappresentati .
Formalizzazione
Concettualmente, i valori intrecciati possono essere pensati come aggregati in cui i diversi componenti mantengono i propri valori, non interferiscono tra loro e possono essere estratti in modo indipendente. Un modo conveniente per pensare a tali aggregati è come n -tuple di valori; per semplicità presumo n = 2 qui. Inoltre, presumo che abbiamo operazioni per costruire tuple da una raccolta di valori e per estrarre i valori dei componenti da una tupla.
Ora dobbiamo essere in grado di eseguire operazioni sulle tuple. per ogni operazione op nel programma originale ora abbiamo 2 versioni: op1 , che opera sul primo componente di una 2-tupla, e op2 , che opera sul secondo componente:
<a1, b1> op1 <a2, b2> = if (b1 == b2) then < (a1 op a2), b1> else undefined
<a1, b1> op2 <a2, b2> = if (a1 == a2) then <a1, (b1 op b2) > br>
Infine (ed è qui che entra in gioco l'offuscamento), abbiamo bisogno di un modo per codificare le tuple come valori e decodificare i valori in tuple. Se l'insieme di valori è S, allora abbiamo bisogno di due funzioni enc e dec che devono essere inverse l'una dell'altra:
enc : S x S -> S (codifica coppie di valori come un singolo valore entangled)
dec : S -> S x S (decodifica un valore entangled nei suoi componenti)
enc ( dec (x)) = x per tutte le x
dec ( enc (x)) = x per tutte le x
Esempi:
-
enc prende una coppia di valori a 16 bit e li incorpora in un valore a 32 bit w in modo tale che x occupi i 16 bit bassi di w e y occupi i 16 bit alti di w; dec prende un valore a 32 bit e li decodifica in una coppia dove x è i 16 bit bassi ey i 16 bit alti.
-
enc prende una coppia <x, y> di valori a 16 bit e li incorpora in una parola a 32 bit w in modo tale che x occupi le posizioni dei bit pari di w e y occupi le posizioni dei bit dispari di w (cioè, i loro bit sono interlacciati); dec prende un valore w a 32 bit e li decodifica in una coppia <x, y> in modo tale che x sia costituito dai bit pari di w e y sia costituito dai bit dispari di w.
Considerazioni sull'implementazione
Dal punto di vista dell'implementazione, vorremmo essere in grado di eseguire operazioni direttamente su rappresentazioni codificate di valori. Per questo, corrispondenti a ciascuna delle operazioni op1 e op2 sopra, dobbiamo definire le versioni "codificate" op1 * e op2 * che deve soddisfare il seguente criterio di solidità:
per tutti x1, x2 e y: x1 op1 * x2 = y IFF enc ( dec (x1) op1 dec (x2)) = y
e allo stesso modo per op2*.
Molti dettagli vengono omessi (per lo più abbastanza facili da elaborare), e questo approccio di base potrebbe essere migliorato in vari modi, ma non lo faccio sapere se questo è sulla falsariga che stavi chiedendo e anche se forse è abbastanza semplice e hai già risolto tutto da solo. Comunque, spero che questo sia utile.
Dal commento di @ perror (sotto) sembra chiaro che la formalizzazione sopra non è abbastanza potente da catturare l'offuscamento che ha in mente (anche se potrebbe essere possibile ottenere un po 'di distanza dalla generalizzazione delle funzioni di codifica / decodifica enc e dec”).
Mi ero dimenticato di questo articolo, che discute di una trasformazione che sembra rilevante (vedi Sezione 6.1, "Variabili divise"): / p>
Christian Collberg, Clark Thomborson e Douglas Low. Rompere le astrazioni e non strutturare le strutture dati. IEEE International Conference on Computer Languages (ICCL'98), maggio 1998. ( link)