Cycle de graine canvas CreepJS : combien de tours restent distincts
CreepJS multiplie une graine canvas par 15000 modulo 2001000001 à chaque tour. Cette sonde mesure combien de tours restent distincts avant que la séquence se répète.
BotBrowser Team
Vous voulez la documentation structurée pour Empreinte ?
Cet article fait partie de la bibliothèque éditoriale. Pour les étapes de configuration, la référence et les mises à jour continues, passez directement à la section docs.
BotBrowser peut rejouer un profil déclaré contre une fixture canvas propre à la page et conserver un enregistrement borné de ce qu’elle a dessiné ; il ne peut pas faire qu’un dessin court représente un long, ni changer la façon dont une bibliothèque fabrique sa propre graine. Le module canvas de CreepJS construit chaque tour à partir d’un état multiplié par une constante puis réduit modulo une autre, et la durée pendant laquelle cette séquence reste distincte avant de se répéter décide de la part réellement neuve d’un long dessin. L’analyse des métriques emoji CreepJS sépare la géométrie textuelle représentative de cette séquence de dessin et des pixels produits.
Résumé
- CreepJS initialise sa graine canvas à 500, multiplie par 15000, réduit modulo 2001000001, puis dessine 10 tours par défaut.
- Ces valeurs publiées donnent 8 valeurs distinctes sur les 8 premiers tirages et 10 positions entières distinctes sur les 10 tours.
- La séquence multiplicative se répète après exactement 26940 tirages, donc le dessin par défaut de 10 tours ne revient jamais sur un état.
- Cinq tours de ce dessin sont un préfixe de dix : une page courte et une page longue partagent leurs cinq premières valeurs.
- Changer seulement la graine déplace la séquence sans changer sa longueur : les graines 500, 501, 1000 et 2000 se répètent toutes à 26940.
- Un rapport qui consigne un digest sans nombre de tours, graine ni révision de la source ne peut pas dire quelle part du dessin était neuve.
Sommaire
- Le générateur publié
- Combien de tours restent distincts
- Ce que signifie un préfixe pour la comparaison
- Où le compte cesse d’informer
- Enregistrer une lecture canvas
Le générateur publié
Le rapport conserve la révision de la source avec la graine et le nombre de tours, afin que la séquence puisse être recalculée hors ligne.
Le module définit un petit générateur et une projection de sa valeur brute vers une coordonnée canvas : Le module est une empreinte canvas : sa première tâche est de dessiner quelque chose dont la lecture diffère entre machines tout en restant identique sur une seule. Le générateur apporte la moitié déterministe, le moteur de rendu l’autre.
source -> https://raw.githubusercontent.com/abrahamjuliot/creepjs/master/src/canvas/index.ts
source_bytes -> 22274 sha256=6bb5e580122bb26343e1fd8108fb2db6e5a719ab8beebf04394779f06139047d
defaults -> seed=500 offset=2001000001 multiplier=15000
rounds_default -> 10
Le générateur garde une valeur courante sous le module. Chaque appel la multiplie par 15000 et prend le reste, et la projection divise par le module, met à l’échelle par la dimension du canvas puis applique un plancher. Les deux étapes sont de l’arithmétique entière sans hasard au moment du tirage, ce qui explique pourquoi la même graine et la même révision de source rendent les mêmes positions de tour.
C’est un choix délibéré. Une empreinte canvas veut rester stable pour une machine et une version de bibliothèque données, donc elle ne peut pas tirer des pixels neufs à chaque appel. Elle part d’une graine et en dérive tout le reste, et la graine est la partie que fournissent la machine ou le profil.
C’est pourquoi le rapport conserve la révision de la source et non une simple URL : le fichier de master change, et les constantes peuvent changer avec lui.
Combien de tours restent distincts
La longueur du cycle sépare aussi deux questions : jusqu’où une séquence peut grandir avant de se répéter, et combien de tours le dessin par défaut utilise.
Avec ces valeurs par défaut, les premiers tirages sont tous différents : Les huit valeurs ci-dessous sont la sortie brute du générateur, avant la division par le module et la mise à l’échelle en pixels, donc deux rapports de tailles de canvas différentes restent comparables sur elles.
first_draws -> 7500000 443999944 671156672 319074969 1733532609 1995122006 1875075045 69660944
first_draws_distinct -> 8 of 8
round_positions -> distinct=10 of 10 rounds
Huit valeurs brutes et dix positions entières, sans répétition. Le dessin par défaut utilise donc dix états distincts, et chacun tombe sur une position différente du canvas. Rien dans l’exécution par défaut n’est dessiné deux fois depuis le même état.
Ce nombre ne couvre que dix états consécutifs du générateur et ne compte pas les états consommés par un tour CreepJS : le module appelle getNextSeed() plusieurs fois par tour, pour le dégradé, l’ombre et la méthode de dessin, donc un tour avance de plus d’un état.
La longueur du cycle dépasse largement celle du dessin :
cycle -> first_repeat_index=0 length=26940
cycle_covers_rounds -> true
26940 tirages avant que la séquence ne revienne à sa valeur de départ. Les 10 tours par défaut utilisent 10 de ces 26940 états, donc le dessin est un très petit préfixe d’une séquence bien plus longue. Une page qui demanderait 500 tours resterait encore sans répétition, et une qui en demanderait 27000 atteindrait le bord du cycle.
Ce que signifie un préfixe pour la comparaison
Un dessin court et un dessin long avec les mêmes paramètres ne diffèrent pas dès le début ; l’un contient l’autre : La même différence entre une graine stable et une surface rendue est ce que l’empreinte canvas consigne côté surface. Une page peut aussi garder un dessin vivant et y ajouter du contenu ; dans cette forme les cinq premiers états du second dessin ne sont pas les premiers de la séquence, donc la propriété de préfixe ne vaut que si la page réensemence.
Un enregistrement sans couche de rendu ne peut pas séparer une séquence différente d’une peinture différente, donc les deux moitiés sont conservées ensemble.
L’enregistrement minimal contient seed, rounds, le digest de la source et la taille du canvas, et note en plus quel moteur de rendu a répondu.
La révision de la source et la taille du canvas sont conservées avec le digest, car un digest seul ne sépare pas la séquence du rendu.
Une comparaison entre machines suit cet ordre : révision de la source, graine, nombre de tours, taille du canvas, moteur de rendu, puis seulement le digest.
La projection applique un plancher plutôt qu’un arrondi : un état à 37.9 tombe sur le pixel 37 et un état à 38.1 sur le 38, donc deux états voisins peuvent partager une coordonnée ou se séparer selon la taille.
La limite d’échelle mérite sa propre lecture : avec un canvas de 50 pixels il n’y a que 50 positions entières par axe, donc deux états différents peuvent se réduire à la même coordonnée ; sur un canvas plus grand ces collisions deviennent plus rares.
Un digest canvas.toDataURL() cache si le dixième tour a été ajouté : les premiers tours avec seed=500 concordent dans les deux cas.
Le rapport porte sur la requête, donc ses champs reflètent la requête et non l’image : une image peut sembler identique après un changement de moteur de rendu, et une requête peut sembler identique après un changement d’échelle, et seul un enregistrement qui sépare les deux champs peut les distinguer.
prefix -> five_rounds_are_prefix_of_ten=true
Cela a une conséquence pratique pour toute comparaison qui stocke un seul digest. Deux pages avec la même graine et un nombre de tours différent produisent des digests différents, parce que le dixième tour change les pixels. Lisez cet écart comme un changement de longueur du dessin, non comme un changement de navigateur. Une revue qui traite tout digest différent comme une différence d’appareil attribuera un paramètre de page à l’environnement.
La même asymétrie apparaît quand une page ajoute un tour. Les cinq premiers états sont intacts, donc une comparaison pixel par pixel sur la zone partagée ne trouve aucune différence tandis que le digest de l’image entière change. Un rapport qui ne garde que le digest complet ne peut pas dire quel tour a été ajouté.
Cette structure explique pourquoi deux rapports CreepJS de pages différentes peuvent diverger en décrivant la même machine. L’état du générateur est déterministe, donc les seules variables sont la graine, le nombre de tours et la révision de la source. Deux pages qui partagent les trois produisent des positions identiques, et deux pages qui ne partagent que la graine divergent dès le premier tour supplémentaire. Une comparaison qui ignore le nombre de tours ne peut pas décider dans lequel de ces cas elle se trouve. Un profil qui rejoue le même dessin entre les visites pose la question de la reproductibilité de la graine de bruit, avec le générateur canvas comme état conservé. Le multiplicateur 15000 et le module 2001000001 sont les deux nombres à conserver, car tout changement les concernant décrit une autre source et non une autre machine.
Où le compte cesse d’informer
Un chiffre exploitable vient du module et du multiplicateur, pas de la graine : La longueur du cycle est une propriété de l’arithmétique modulaire, non de la graine : à module et multiplicateur fixes, tout point de départ premier avec le module parcourt le même cycle, et un point qui partage un facteur en parcourt un plus court.
La valeur multiplier=15000 et le module offset=2001000001 la fixent, donc un rapport peut citer les deux et vérifier gcd avant de comparer deux exécutions.
seed:500 -> cycle=26940 draws_8_distinct=1
seed:501 -> cycle=26940 draws_8_distinct=1
seed:1000 -> cycle=26940 draws_8_distinct=1
seed:2000 -> cycle=26940 draws_8_distinct=1
Toutes les graines testées se répètent à 26940 tirages, parce que le module et le multiplicateur fixent la longueur du cycle pour tout point de départ premier avec le module. La graine choisit où commence le dessin dans la séquence ; elle ne change pas la durée de cette séquence.
La seconde colonne de cette sortie trompe volontairement, et montre un piège de mesure. La sonde recréait le générateur à l’intérieur d’une seule expression pour chacun des huit tirages, donc chaque appel repartait de la graine et rendait la même première valeur. Une sonde écrite ainsi rapporte une valeur distincte et conclut que le générateur est dégénéré. La lecture correcte est celle mesurée plus haut : huit valeurs distinctes d’une seule instance. Un rapport fondé sur le seul digest peut confondre une page qui réinitialise le générateur avec une page qui le continue.
Ce piège mérite d’être énoncé parce que c’est la façon la plus courante pour une sonde de graine de produire un faux positif. Créer le générateur dans la boucle, ou le réinitialiser entre les tirages, mesure la première valeur encore et encore sans jamais toucher la séquence.
Le détail du multiplier=15000 et du offset=2001000001 est conservé avec la graine, car sans eux la séquence ne peut pas être recalculée hors ligne.
Une page qui dessine plus de 26940 tours verrait un état répété, et une page qui en dessine des milliers resterait largement dans le cycle ; le dessin par défaut de rounds=10 est très loin de cette limite.
Enregistrer une lecture canvas
Une lecture canvas soutient une affirmation étroite : cette révision de source, cette graine et ce nombre de tours ont produit ces positions distinctes. Quatre champs la gardent vérifiable :
- La révision et le digest de la source, car un changement de multiplicateur ou de module change chaque tirage.
- La graine et le nombre de tours, car ils décident de la partie de la séquence utilisée.
- Les comptes d’états et de positions distincts, car un digest seul ne dit pas si un tour a été ajouté ou si la graine a bougé.
- La durée de vie du générateur, car le recréer à chaque tirage transforme la séquence en une première valeur répétée.
L’article des tables de polices lit un troisième ensemble de tables publiques de la même façon, et ses comptes et ses groupes accompagnent le cycle de graine canvas.
Sources publiques
- CreepJS
- Module canvas de CreepJS
- MDN : CanvasRenderingContext2D
- BotBrowser : référence de cohérence d’automatisation
Conclusion pratique
Consignez la graine, le nombre de tours et la révision de source avec chaque comparaison canvas, car un digest seul ne distingue pas un dessin plus long d’un dessin différent. Traitez cinq tours comme un préfixe de dix quand la graine et la révision concordent, et attendez-vous à ce que le digest diffère quand même. Lisez le cycle de 26940 tirages comme la distance que peut parcourir un dessin avant de se répéter, non comme une propriété des dix tours par défaut. Pour l’arithmétique derrière une comparaison canvas plus longue, lisez comment CreepJS regroupe ses signaux canvas ; pour la frontière entre une lecture côté page et une lecture côté connexion, lisez les règles de couche réseau qu’une page ne peut pas évaluer.
Cet article fait partie du guide : Qu'est-ce qu'une empreinte de navigateur ?
Articles Connexes
Mode déterministe : empreintes reproductibles
EmpreinteReproductibilité de la graine de bruit pour des exécutions répétables
EmpreinteMétriques emoji CreepJS : ensembles et sommes
EmpreinteEmpreinte Canvas : fonctionnement et solutions
EmpreinteFingerprinting par mesure de texte : suivi sous-pixel
EmpreinteTables CreepJS : 51 noms et 14 retours possibles
Faites passer BotBrowser de la recherche à la production
Utilisez ces guides pour comprendre le modèle, puis passez à la validation multi-plateforme, aux contextes isolés et au déploiement navigateur prêt pour l'échelle.