Codage et décodage des chaines analogiques de 1984 à 2010 (partie 1)

Un peu d’histoire

Je vais vous parler du système de codage des chaines lorsqu’elles émettaient en analogique en France. Je sais que ces temps n’ont plus cours car de nos jours la TNT a remplacé les signaux analogiques mais je sais aussi que toute une communauté de passionnés d’électronique (dont moi-même) porte un intérêt certain à ces sujets. En novembre 1984, arrivait en France, une nouvelle chaine cryptée et payante suscitant beaucoup d’intérêt chez les amateurs d’électronique et de films débridés. C’est ainsi que cette chaine de télévision et les électroniciens se sont livrés à une bataille sans relâche entre 1984 et 1996. Cet article est une tentative d’explication des techniques employées pour crypter et décrypter les images (et non une apologie du piratage)
Ma connaissance de ces systèmes vient d’une part des publications de cette époque, et de mes observations personnelles d’autre part. Il se peut que des données soient inexactes, je ne me prétends pas expert sur ce sujet . Je mettrai l’article à jour si je retrouve des notes plus précises ou si vous même pouvez y contribuer par vos remarques et observations.
Dans la seconde partie, il sera question des dispositifs imaginés par ces virtuoses de la bricole. Je passerai en revue tous les systèmes que j’ai approchés ou étudiés il y a 25 ans. Justement, il y a 25 ans j’avais utilisé le ZX Spectrum pour illustrer le codage. J’avais utilisé l’image de chargement du jeu « Their Finest Hours » et j’avais décalé aléatoirement les lignes de 0, 8 ou 16 bits sur 3 images que j’affichais à la suite. test_180-270_optimized Pour comprendre la suite et savoir comment fonctionnait ce décryptage il nous faut quelques rudiments en termes de signaux TV analogiques

Les signaux TV analogiques

Une image de télévision analogique est composée de 2 trames elles même chacune composées de 312 lignes et demie. Les trames qui portent les lignes de 1 à la 313,5 sont dites impaires et celles qui portent les lignes 313,5 à 625 sont dites paires. Une image est donc un ensemble de 625 lignes dont les trames sont entrelacées et diffusées en alternance. En réalité seules 575 lignes par images sont visibles sur l’écran.

Balayage des trames paires et impaires

Balayage des trames paires et impaires

Chaque ligne à une période de 64µs dont seulement 52µs sont visibles. La fréquence des tops ligne est donc de F = 1/64µs soit 15625Hz. La période des trames est T = 312.5 * 64µs soit 20ms, ce qui fait une fréquence de 50Hz

Allure du signal d'une ligne de TV

Allure du signal d’une ligne de TV

La détection du changement de trame repose sur une inversion temporaire du rapport cyclique du signal

Détection du changement de trame

Détection du changement de trame

Pour de plus amples informations je vous invite à consulter la page http://f5ad.free.fr/ATV-QSP_F5AD_Le_signal_video.htm

1984 – Système Discret 11

De par l’observation, le codage des images n’est pas si compliqué. Il est réalisé en décalant selon une séquence aléatoire, l’information vidéo de chaque ligne d’un retard de 0, 900 ou 1800 nanosecondes. La séquence est modifiée tous les premiers lundi du mois à 9H. La séquence complète se répète toutes les 120ms car elle s’effectue sur 3 images, soit 6 trames représentant 1875 lignes (6 *   625/2). Cette fameuse séquence pseudo aléatoire repose sur un polynôme de type P(X) = X11 + X9  + 1 dont la période est 2¹¹ – 1 soit 2048 – 1 = 2047 ce qui couvre bien la totalité des lignes qu’il faut coder. En revanche il est nécessaire de réinitialiser la séquence régulièrement puisque le nombre de solutions est supérieure au nombre de lignes codées.

Le générateur pseudo aléatoire

Les caractéristiques du générateur sont les suivantes:

  • Il doit avoir une récurrence cyclique de 2047
  • Il doit être capable de se recharger en mode parallèle avec un code de 11 bits
  • Il doit effectuer des rotations

La particularité de la récurrence cyclique de 2047 sera mise à profit pour retrouver le code d’initialisation si, à un moment donné, on connait le contenu du registre, il suffit d’effectuer le complément à 2047 rotations pour remonter au code d’origine. Pour les rotations, ce sont bien entendu les tops lignes qui vont faire avancer le générateur Dans la pratique le codage ne s’effectue pas sur toutes les lignes mais uniquement sur 286 lignes par trame.

  • Lignes 24 à 309 incluses pour les trames impaires
  • Lignes 337 à 622 incluses pour les trames paires

Le système sera donc incrémenté avec les tops des lignes 25 à 310 des trames impaires et 338 à 623 des trames paires. Pendant les lignes non incluses dans cette définition, le générateur de séquence n’évolue pas Pour que le générateur pseudo aléatoire se recharge avec le mot d’initialisation (le code du mois) une information de synchronisation est nécessaire. C’est la ligne 310 des trames impaires qui va fournir cette information. Lorsqu’elle est forcée au niveau blanc, le générateur est réinitialisé.

Activité de la ligne 310 et top trame paire

Activité de la ligne 310 et top trame paire

Si on désigne par ‘1’ le niveau blanc et par ‘0’ le niveau noir de cette ligne, sa séquence est répétitive et est formée par le pattern  1 0 0 1 0 0 1 0 0 1. Le générateur est réalisé par un registre à décalage constitué de 11 bits dont les bits b8 et b10 sont combinés dans une porte « ou exclusif » pour reformer le prochain bit b0

Générateur pseudo aléatoire de type X11 + X9 + 1

Générateur pseudo aléatoire de type X11 + X9 + 1

Voici comment les choses se passent: Lorsque le système détecte que la ligne 310 d’une trame impaire est blanche, le registre est initialisé avec le code du mois, c’est le début d’un cycle. L’incrémentation du générateur est bloquée et le premier code P0 est appliqué à la ligne 337 de la trame paire suivante. Ensuite le top de la ligne 338 fait avancer le code d’un cran et P1 lui est alors appliquée. Le processus se répète jusqu’à la ligne 622 pour laquelle P285 est appliqué. La ligne 623 incrémente le code d’un cran et l’incrémentation est bloquée. La ligne 24 de la trame impaire suivante reçoit P286 et c’est le top ligne 25 qui fait à son tour avancer le code pour recevoir P287. De nouveau le processus se répète jusqu’ à la ligne 309 qui reçoit P571. La ligne 310 (qui est noire celle ci) fait avancer le code d’un cran. Ouf on vient de parcourir une image.. Tout ce cycle recommence 2 fois pour les 2 images suivantes. Il se termine par la ligne 309 de la dernière trame impaire qui reçoit P1715. La ligne suivante est la 310 elle sera blanche. Le code est incrémenté de 1 mais peu importe puis la synchronisation trame va remettre le code P0 dans le générateur. Et on repart pour un nouveau cycle.

Codage des lignes avec le polynôme associé

Codage des lignes avec le polynôme associé

Construction de la table des retards

Les bits b10, b0 du générateur de séquence vont nous servir à construire la table des retards. Cependant pour introduire un tremblement horizontal de l’image un troisième bit Z est utilisé. il est construit à l’aide d’un compteur, qui permet de diviser par 6 la fréquence de synchronisation trame. Z vaut donc ‘0’ pour les trames 1, 2, 3 et ‘1’ pour les trames 4, 5 et 6.

Table des retards en fonction de Z b0,et b10

Table des retards en fonction de Z b0,et b10

 

Septembre 1987 – le multicode et le brouillage des débuts des lignes

Le brouillage des débuts des lignes

Avant septembre 1987, les départs des lignes étaient au niveau infra-noir jusqu’à l’apparition du signal vidéo retardé. Il était alors possible de faire une analyse des lignes pour détecter le départ réel du signal vidéo et de lui appliquer ou non le retard désiré. La contre mesure consiste à insérer de façon aléatoire un signal de brouillage au début des lignes, ce qui rend impossible la détection des retards. Tous les décodeurs reposant sur cette technique ont été immédiatement et irrémédiablement rendus inopérants. Ce fut le cas pour le décodeur de Radio Plans et le DC4

Le multicode

Jusqu’à maintenant, comme nous venons de le voir, un seul polynôme d’initialisation de 11 bits était utilisé. Certains décodeurs mémorisaient le code du mois à l’aide d’interrupteurs et fonctionnaient pendant un mois. Avec cette nouvelle astuce, ce n’était plus possible, car 6 polynômes sont utilisés. A l’origine 6 « niveaux d’audience » avaient été prévus afin de segmenter les abonnements et offrir un bouquet thématique. 6 bits dans la clé périodique de 16 bits permettaient d’autoriser l’accès à ces autres niveaux (1 bit par niveau ce qui explique nos 6 polynômes de 11 bits). Cette possibilité n’ayant pas vu le jour, elle a été utilisée pour mettre à profit le multi code. Les polynômes sont liés entre eux par un décalage à gauche de 3 bits. Ci dessous un exemple de la rotation des polynômes pour le mois de février 1988. Outre le code du mois, 5 autres polynômes alternés sont présents. En plaçant les codes les uns en dessous des autres et en tenant compte du décalage de 3 bits on arrive à former un code de 26 bits.On observe qu’il se répète au bout de 16 bits.

Rotation du polynôme d’initialisation avec le multicode en février 1988

Rotation du polynôme d’initialisation avec le multicode en février 1988

En réalité, chaque polynôme n’utilise que 11 bits du code complet de 16 bits. Le bit b11 du polynôme 6 étant le bit b0 du code complet. Le bit b11 du polynôme 1 est le bit b15 du code complet.
Dans le tableau ci dessous, une croix indique un élément de la clé complète non utilisé dans le polynôme correspondant.

Utilisation des bits du code complet selon les polynômes (une croix indique un bit non utilisé)

Utilisation des bits du code complet selon les polynômes (une croix indique un bit non utilisé)

Comment ces polynômes sont-ils utilisés et à quel moment les utiliser ? C’est la ligne 622 des trames paires qui fournit l’indication. Comme le codage est effectué sur 3 images, 3 lignes 622 sont disponibles à la sélection d’un des 6 polynômes possibles. En effet, nous avons vu que le cycle commence par une ligne 310 d’une trame impaire au niveau blanc, viennent ensuite pour la première image une ligne 622, puis une ligne 310 noire, puis pour la seconde image une ligne 622 et une autre ligne 310 noire et enfin pour la troisième image une ligne 622 et une ligne 310 blanche qui indique le début d’un nouveau cycle. Il est alors possible d’établir une table de vérité.

Sélection du polynôme à appliquer en fonction du niveau de ligne 622

Sachant le polynôme « 0 » correspond à une diffusion en clair et que le polynôme 7 est le code d’accès libre (code de transition en fin de mois pour permettre aux abonnés de recevoir leur code par la poste et de l’entrer dans la machine) il reste 6 polynômes disponibles pour l’initialisation du générateur pseudo aléatoire. Cette initialisation ne sera pas effective tout de suite mais interviendra après 8 (et non pas 9 merci LSFR) cycles de 6 trames (l’ancien polynôme restera donc actif encore 8 * 120ms). Ce qui  revient également à dire que les polynômes peuvent changer pratiquement toutes les secondes. Les systèmes devront désormais ne plus se fier aux débuts des lignes et conserver 6 codes en mémoires en analysant les lignes 310 et 622.
Ci dessous le code analysant les niveaux d’audience.

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// EXAMINE LE NIVEAU D'AUDIENCE ET REGARDE SI
// IL SE REPETE
// szMemory0[19] CONTIENT LE NIVEAU DE LA LIGNE 622 BIT PAR BIT
// szMemory0[21] EST LE COMPTEUR D'OCCURENCES
// szMemory0[20] CONTIENT LE NOUVEAU NIVEAU D'AUDIENCE EN B3 B2 B1 0
// SI ON L'OBSERVE 8 FOIS
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
void B19_T2(){
// 2 MICROSECONDES
// NOP
// szMemory0[19] CONTIENT LES VALEURS DE PA0 DANS SES 8 BITS
// LDA 19
szREGISTREA = szMemory0[19];
// DECALAGE DE 3 BITS A GAUCHE
// LSL A
// LSL A
// LSL A
szREGISTREA <<= 3;
// OU EXCLUSIF AVEC LE CONTENU 19
// EOR 19
szREGISTREA ^= szMemory0[19];
// B7 B6 B5 B4 B3 B2 B1 B0
// XOR
// B4 B3 B2 B1 B0 0 0 0
// B2^B5 B1^B4 B0^B3
// AND #%00111000
// NE GARDE QUE B5^B2 B4^B1 B3^B0
szREGISTREA &= 0x38;
// BNE 19FAIL
// szREGISTREA VAUT 0 SI
// LES BITS B5 ET B2 SONT IDENTIQUES
// ET
// LES BITS B4 ET B1 SONT IDENTIQUES
// ET
// LES BITS B3 ET B0 SONT IDENTIQUES
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// MEME COMBINAISON XXX SUR LA LIGNE 622
// SUR SEQUENCE N ET N + 1
if(0 == szREGISTREA){
// ON COMPTE COMBIEN DE FOIS ON A EU CETTE COMBINAISON
// INC 21
szMemory0[21]++;
// EST-CE QUE CA FAIT 7 FOIS ?
// PASSAGE 1 N = N + 1
// PASSAGE 2 N + 1 = N + 2
// PASSAGE 3 N + 2 = N + 3
// PASSAGE 4 N + 3 = N + 4
// PASSAGE 5 N + 4 = N + 5
// PASSAGE 6 N + 5 = N + 6
// PASSAGE 7 N + 6 = N + 7
// CE QUI FAIT DONC 8 SEQUENCES CONSECUTIVES
// CMP #7
// BNE EXIT2
if(7 == szMemory0[21]){
// CHARGE LA VALEUR DU NIVEAU D'AUDIENCE
// LDA 19
szREGISTREA = szMemory0[19];
// NE GARDE QUE LES 3 DERNIERS BITS (B2 B1 B0)
// AND #%00000111
szREGISTREA &= 0x07;
// LES INVERSE
// EOR #%00000111
szREGISTREA ^= 0x07;
// DECALE DE 1 BIT
// LSL A
szREGISTREA <<= 1;
// szMemory0[20] CONTIENT NIVEAU D'AUDIENCE DANS B3 B2 B1
// STA 20
szMemory0[20] = szREGISTREA;
}else{
// EXIT2 RTS
return;
}
// 19FAIL
// CLR 21
szMemory0[21] = 0;
}
}
Analyse des niveaux d'audience

La table des retards se calcule avec la fonction suivante.

//---------------------------------------------------
/**
* createDiscretDelay:  creation de la table des retards
*
* @param nInitCode     : Code d'initialisation du générateur (code du mois si trame 0, code retournée par la fonction sinon)
* @param szFrameNumber     : Numero de la trame (0 à 5)
* @param pszDelay     : pointeur vers la table a remplir
* @return le code du générateur pseudo apres les rotations
*/
//---------------------------------------------------
unsigned int createDiscretDelay(unsigned int nInitCode, unsigned char szFrameNumber,unsigned char* pszDelay){
// On ne garde que 11 bits
unsigned int nCode = nInitCode & 0x7FF;
unsigned int nI;
unsigned int z = szFrameNumber / 3;
unsigned int b10,b8,b0;
unsigned int delayArrayIndex;
for(nI = 0; nI < K_NB_LIGNES_TOTAL_A_PERMUTER - 1; nI++){ // Isoler b10 b10 = ((nCode & 0x400) >> 10) & 0x01;
// Isoler b8
b8  = ((nCode & 0x100) >> 8) & 0x01;
// Calculer index du tableau
// bit Z
delayArrayIndex  = (z & 0x1) << 2;
// Bit Y (b0 du polynome)
delayArrayIndex |= (nCode & 0x01) << 1;
// Bit X (b10 du polynome)
delayArrayIndex |= b10 ;
// Remplir tableau des retards
pszDelay[nI] = szDelay[delayArrayIndex];
// Decaler le registre
nCode = (nCode << 1); // Faire le ou exclusif b0 = b10 ^ b8; // Injecter b0 dans le code nCode |= b0; // Ne garder que 11 bits nCode &= 0x07FF; } // On fait un tour de plus pour préparer le code // de la prochaine trame. b10 = ((nCode & 0x400) >> 10) & 0x01;
b8  = ((nCode & 0x100) >> 8) & 0x01;
b0 = b10 ^ b8;
nCode = (nCode << 1);
nCode |= b0;
nCode &= 0x07FF;
return nCode;
}
Algo retard trame

Ce qui nous donne avec l’exemple du code du mois de février, pour les 286 lignes de la première trame

Table des retards en fonction de Z b0,et b10

Table des retards en fonction de Z b0,et b10

1995 – Un nouveau système : le Nagravision

Après 10 années de service, le système Discret 11 est abandonné et un  nouveau codage voit le jour. Les nouveaux décodeurs Syster sont envoyés aux abonnés. Ils prennent en charge le codage Discret11 et le Nagravision pour assurer la transition. Au premier regard, on constate que ce codage est plus compliqué que le Discret 11. Les lignes sont toutes mélangées, l’image est en noir et blanc. On trouve sur le net des explications du système Nagravision (notamment par le bais du brevet déposé par la société Kudelski). N’étant pas très familier avec ce système, je me contenterai d’une synthèse de ce que j’en ai compris. Dans ce qui suit, pour des raisons de simplification, on suppose que la mémoire peut contenir 32 lignes de TV numérisées sur 8 bits. Le dispositif contient donc une mémoire pouvant stocker 32 lignes de TV numérisée. Lorsqu’une nouvelle ligne arrive, elle est numérisée par un convertisseur analogique/numérique puis, elle prend la place d’une des lignes déjà stockée. Cette ligne qui sort est reconvertie par un convertisseur numérique/analogique puis dirigée vers la sortie TV. Ce principe est illustré dans la figure ci dessous.

Mémoire des lignes TV et remplacement des lignes sortantes

Mémoire des lignes TV et remplacement des lignes sortantes

On voit que l’ordre d’affichage des lignes sur le téléviseur est fonction des positions en mémoire des lignes entrantes. La réciproque est aussi vraie. On ne pourra insérer une ligne en mémoire que lorsqu’une des lignes présentes en mémoire sera affichée sur la TV. En effet une ligne Z venant prendre la place d’une ligne X ne sortira à l’affichage que lorsqu’elle sera elle même remplacée par une autre ligne Y. On peut jouer sur ces deux constats pour décider de l’ordre de sortie des lignes vers la TV mais aussi de l’ordre d’entrée des lignes dans la mémoire. Pour chaque trame, le système doit maintenir une table mettant en correspondance le numéro des lignes de l’image non embrouillée et leur position en mémoire puis retirer de cette table les lignes qui sont envoyées au téléviseur. Enfin on trouve autant de fifos que de positions mémoires disponibles (F0 à F31 dans notre cas). Dans ces fifos, on empile, en commençant par les dernières lignes d’une trame et en remontant vers les premières, les numéros des lignes qui, lors de leur réception, seront stockées dans la position mémoire correspondant au rang de la fifo. Par exemple si la fifo P0 contient [309, 306, 300..], les lignes 309, 306 et 300 seront stockées à la position 0 de la mémoire. Cette technique permet de réaliser notre double codage. Voici comment : lorsque toutes les piles sont constituées, on procède au désempilement de toutes les fifos en commençant par F0. Dans notre exemple les lignes 309, 306 et 300 sont extraites, ce qui signifie qu’à la position 0 en mémoire une ligne 309 entrante viendra remplacer une ligne 306 sortante et qu’une ligne 306 entrante remplacera une ligne 300 sortante. Les permutations sont relatives et non absolues et le numéro des lignes qui sont envoyées sur la TV est une fonction d’une part de sa position en mémoire mais aussi du numéro de la ligne qui viendra la remplacer. On comprend que l’algorithme du code est compliqué et qu’il sera difficile de le percer car il réside dans l’agencement des fifos et dans l’ordre d’envoi des lignes vers la TV. Pourtant c’est encore l’observation – et une particularité française – qui va venir au secours des bricoleurs. La diffusion en SECAM, dont les lignes ne portent qu’une moitié de l’information couleur va permettre de reformer l’image. Nous avons vu que le principe du codage était de permuter les lignes, ce qui se traduit également par une permutation aléatoire des informations couleur que portent les lignes (ce qui explique au passage que l’image codée était en noir et blanc). En effet, partant du fait que deux lignes consécutives décodées portent ensemble l’information complète de couleur (R-Y-B-Y) et en sachant que le nombre de permutations pour retrouver ces deux lignes parmi les blocs de lignes codées est limité, de nouveaux décodeurs utilisant ce principe sont apparus. En effet si on considère que les lignes sont permutées par bloc de 32, selon une table primaire dont l’offset peut prendre 256 valeurs différentes, de 0 à 255 et dont l’incrément doit être impair, il ne peut donc prendre que 128 valeurs de 1 à 255. Le nombre total de permutations possibles est de 128 * 256 = 32768 permutations possibles pour retrouver la ligne correspondante. En utilisant une table de hashage pour accélérer la recherche il devient possible de faire le traitement en temps réel.

La mise en œuvre

La réalisation est en effet une permutation de 32 lignes dans chaque trames du signal vidéo à partir d’une table fixe. L’ordre des 32 lignes dans la trame dépend d’un mot de 64 bits issu d’un algorithme DES pseudo aléatoire. Disons que ce mot est calculé à partir d’éléments fournis par des informations extraites du télétexte et n’est valable que pour les 2 prochaines secondes et que des droits d’accès sont vérifiés périodiquement. Pour la première trame les 32 lignes sont choisies en bas de l’image, puis en haut pour la seconde et enfin au milieu pour la troisième trame. En ne sélectionnant pas toujours les mêmes 32 lignes (selon une rotation cyclique tout de même) on a une impression de cryptage. Pour permettre le traitement en temps réel, les 32 lignes de la prochaine image apparaissent déjà désordonnées en bas de l’image cryptée. Ainsi le décodeur peut mettre en mémoire et traiter les 32 lignes de la prochaine image pour les transmettre dans le bon ordre. On doit prendre les 32 dernières lignes de la trame courante et les 255 premières lignes de la trame suivante pour former une image.

La table des permutations

Chaque entrée dans cette table correspond à la position dans la mémoire de 32 lignes que devra prendre la ligne TV dont le rang est l’index de la table Par exemple si on trouve 15 à l’index 0, cela signifie que la première ligne devra être stockée en position 15. La table des permutations est réalisée par le bout de code suivant :

const int K_NB_LIGNES_TOTAL_A_PERMUTER = 287;
const int K_NB_GROUPE_DE_LIGNES_A_PERMUTER = 32;
//---------------------------------------------------
/**
* createPermutation: creation d'une table de permutation
* La table de permutation générée contient 287 entrées qui désignent la position en mémoire (donc entre 0 et 31)
* que devra prendre la ligne dont le rang est l'index de la table.
*
* Le nombre de permutations différentes possibles est 256 * 128 soit 32768
*
* @param szTabSelect : Selectionne la table primaire (2 = table2, autres valeurs = table1)
* @param szOffset : Offset de départ de la table [0 - 255]
* @param szIncrement : Increment pour le parcours de la table, doit être impaire dans la limite de [1 - 255]
* @param pszPermut : Pointeur vers la table de permutation qui sera générée
* @return true si la table a ete generee, false sinon
*/
//---------------------------------------------------
bool createPermutation(unsigned char szTabSelect, unsigned char szOffset, unsigned char szIncrement, unsigned char* pszPermut){
bool isRes = false;
unsigned char* pszKeyTable;
unsigned char szJ;
unsigned int nI;
// On vérifie que le pointeur n'est pas nul et que l'increment est impaire
if((NULL != pszPermut) && ( 1 == (szIncrement & 1))){
// Selectionne la table 1 par défaut
pszKeyTable = szKeyTableLevel1;
if(2 == szTabSelect){
pszKeyTable = szKeyTableLevel2;
}
// On commence le parcours à l'index szOffset
szJ = szOffset;
// Pour produire les 255 premiers nombres, la table primaire est lue 255 fois,
// en commençant par une des 256 lignes (offset), et en la parcourant circulairement avec
// un certain pas (l'incrément).
for (nI = 0; nI < 255 ;nI++){
pszPermut[nI] = pszKeyTable[szJ];
// Comme szJ est un unsigned char il tourne de 255 à 0 quand il overflow
szJ += szIncrement;
}
// Les 32 derniers nombres doivent être dans l'ordre naturel,
// afin de remplir correctement le buffer avec les 32 premières lignes de la trame
// suivante pendant qu'on visualise les 32 dernières lignes de la trame courante.
for (nI = 255 ; nI < K_NB_LIGNES_TOTAL_A_PERMUTER; nI++){
pszPermut[nI] = nI - 255;
}
isRes = true;
}
return isRes;
}
Fonction de calcul des permutations

Ce qui donne par exemple pour un offset de 10 et un incrément de 13 en utilisant la table primaire numéro 1, la table de permutations suivante:

Table de permutations

Table de permutations

La première ligne cryptée sera donc stockée à la position 15 de la mémoire, la seconde ligne à la position 21 jusqu’à la dernière ligne qui sera stockée en position 31. Nos 287 lignes savent donc maintenant ou elles vont être stockées. Si l’on regarde comment les fifos vont être remplies avec le code suivant

//---------------------------------------------------
/**
* showFiFo
*/
//---------------------------------------------------
bool showFiFo(unsigned char* pszPermut){
signed int nI;
unsigned int nStack[9][K_NB_GROUPE_DE_LIGNES_A_PERMUTER];
unsigned char szStackPointer[K_NB_GROUPE_DE_LIGNES_A_PERMUTER];
if(NULL != pszPermut){
// Initialisation des pointeurs de pile
memset(szStackPointer,0,K_NB_GROUPE_DE_LIGNES_A_PERMUTER * sizeof(unsigned char));
// Remplissage des piles. La ligne qui correspond à ligne du buffer est empilée
for (nI = K_NB_LIGNES_TOTAL_A_PERMUTER - 1; nI >= 0; nI--){
int nPositionPile = szStackPointer[pszPermut[nI]];
int nNumeroDePile = pszPermut[nI];
int nLignes = nI;
nStack[nPositionPile] [nNumeroDePile] = nLignes;
szStackPointer[pszPermut[nI]]++;
}
}
return true;
}
Remplissage de fifos

On obtient le tableau de remplissage ci dessous

Remplissage des fifos

Remplissage des fifos

La première ligne TV (index 0) est bien positionnée au niveau 0 de la fifo F15 Il ne reste plus qu’à obtenir la table de décryptage pour savoir quel est l’ordre a suivre pour reconstituer l’image. C’est chose faite avec cette fonction

//---------------------------------------------------
/**
* showFiFo
*/
//---------------------------------------------------
bool showFiFo(unsigned char* pszPermut){
signed int nI;
unsigned int nStack[9][K_NB_GROUPE_DE_LIGNES_A_PERMUTER];
unsigned char szStackPointer[K_NB_GROUPE_DE_LIGNES_A_PERMUTER];
if(NULL != pszPermut){
// Initialisation des pointeurs de pile
memset(szStackPointer,0,K_NB_GROUPE_DE_LIGNES_A_PERMUTER * sizeof(unsigned char));
// Remplissage des piles. La ligne qui correspond à ligne du buffer est empilée
for (nI = K_NB_LIGNES_TOTAL_A_PERMUTER - 1; nI >= 0; nI--){
int nPositionPile = szStackPointer[pszPermut[nI]];
int nNumeroDePile = pszPermut[nI];
int nLignes = nI;
nStack[nPositionPile] [nNumeroDePile] = nLignes;
szStackPointer[pszPermut[nI]]++;
}
}
return true;
}
Table de decryptage

La table obtenue est de cette forme

Table de decryptage

Table de décryptage

 

Novembre 1997 – Contre mesure, changement de table primaire et codage couleur

Bien que le coût et la complexité des nouveaux dispositifs imaginés par les bricoleurs se soient accrus, ils se sont tout même répandus. Et la contre mesure est arrivée. Afin de ne plus pouvoir retrouver les deux lignes consécutives à partir de leurs informations de couleur, l’algorithme du codage était calculé tous les mois afin de restituer une alternance R-Y-B-Y. Par exemple une ligne 300 portant l’information R-Y était placée juste avant une ligne 308 portant l’information B-Y. L’alternance R-Y-B-Y étant de nouveau quasi respectée, l’image codée reparue de nouveau en couleur et les dispositifs pourtant élaborés furent rendus inopérants (?).

2010 – Arrêt de la diffusion en analogique

Depuis 2010 la TV analogique a cessé d’émettre. Maintenant un écran noir tout moche à pris la place de nos belles lignes agitées lorsque la chaine est cryptée. Il n’y a plus rien à observer. Le contrôle d’accès étant réalisé par une carte à puce. Nous en reparlerons dans un autre article consacré à Viaccess et Mediaguard. liens : http://www.rennes.supelec.fr/ren/perso/jweiss/tv/signal/tv_opt.pdf http://claude.lahache.free.fr/mapage2/introduction-tv-v2.pdf http://www.cl.cam.ac.uk/~mgk25/nagra.pdf http://cricrac.free.fr/download/Doc/ALGORITH.HTM