- Es un crate de Rust que detecta patrones de esvástica que pueden aparecer por casualidad en códigos QR y, opcionalmente, genera códigos QR sin ese patrón
- Renderiza los 8 patrones de máscara del estándar QR para filtrar candidatos sin el patrón, y luego elige la máscara con la penalización ISO/IEC 18004 más baja
- Excluye de la inspección los módulos de finder, timing, alineación, formato y versión, y considera el contraste con el entorno para no confundir elementos funcionales o formas invisibles con el patrón
- El detector predeterminado no tiene dependencias externas y prohíbe código
unsafe, y admite varias bibliotecas de QR y la representaciónVec<Vec<bool>> - El alcance de detección se limita a cruces gamadas de 5×5 y 7×7 alineadas al eje, en ambas orientaciones y con ambas polaridades de color; no admite formas a 45 grados, diagonales ni rotaciones arbitrarias
Por qué evitar patrones accidentales
- qr-swastika-avoider detecta y evita patrones de esvástica que pueden aparecer aleatoriamente en códigos QR
- Los códigos QR eligen el patrón con mejor puntuación de legibilidad entre 8 patrones de máscara intercambiables, pero no revisan símbolos que puedan resultar ofensivos
- Los patrones pequeños y finos son difíciles de filtrar durante el proceso de evaluación del estándar QR, por lo que pueden quedar accidentalmente en el código final
Detección considerando elementos funcionales y contraste
- El detector predeterminado no tiene dependencias externas y aplica
#![forbid(unsafe_code)] - Permite inspeccionar distintos formatos de representación QR mediante un trait pequeño,
QrModules, compuesto por dos métodos - Excluye de la detección los módulos de finder, timing, alineación, formato y versión, para no confundir las esquinas del finder con una esvástica
- Los patrones que quedan enterrados dentro de módulos del mismo color y no son realmente visibles se ignoran según el contraste con el entorno, y este criterio es ajustable
- Los códigos QR existentes pueden inspeccionarse con
contains_swastika; si se encuentra el patrón, se puede regenerar el código o advertir al usuario
Representaciones QR y bibliotecas compatibles
- Ofrece los siguientes adaptadores mediante features de Cargo
qrcodegen:QrModulesparaqrcodegen::QrCodeqrcode:QrModulesparaqrcode::QrCodefast_qr:QrModulesparafast_qr::QRCode
- También admite la matriz de módulos sin procesar
Vec<Vec<bool>>sin adaptador adicional;trueindica un módulo oscuro
Generación de códigos QR sin el patrón
encode_safe, de la featuregenerate, recibe el contenido y el nivel de corrección de errores, y devuelve un código QR escaneable sin el patrón; si no se puede generar, devuelve un error explícito- Durante la generación, renderiza las 8 máscaras y conserva solo los candidatos que no contienen el patrón objetivo
- Entre los candidatos restantes, devuelve la máscara con la penalización ISO/IEC 18004 más baja para mantener la optimización de legibilidad del estándar
- Con
matrix()del valor devuelto se puede obtener la matriz de módulos, y conmask()se puede consultar la máscara seleccionada
Configuración de features de Cargo
- Las features predeterminadas incluyen solo el detector sin dependencias
- Las features
qrcodegen,qrcodeyfast_qragregan adaptadores para cada biblioteca - La feature
generateincorporaqrcodegencomo dependencia y ofreceencode_safe
Alcance de detección y licencia
- Detecta, dentro de una pequeña tolerancia, cruces gamadas clásicas alineadas al eje de tamaños 5×5 y 7×7, en ambas orientaciones y con polaridades clara y oscura
- Las formas a 45 grados o diagonales, y las formas rotadas en ángulos arbitrarios, no están incluidas en el alcance de detección
- Se distribuye bajo la MIT License
1 comentarios
Opiniones en Lobste.rs
Me resulta confuso que este proyecto evite la esvástica religiosa, pero no la esvástica que usaron los nazis. El símbolo nazi está rotado 45 grados, y el proyecto indica explícitamente que “los motivos de 45 grados/diagonales y las rotaciones arbitrarias quedan fuera del alcance”.
Las imágenes que aparecen por casualidad en un código QR tienen baja resolución, así que es más probable que justamente la forma sin rotar se reconozca claramente como una esvástica, y no como un patrón aleatorio de píxeles. Tiene sentido enfocarse en eso.
Además, dice que “se excluyen los módulos de finder, timing, alineación, formato y versión para no confundir las esquinas del finder con esvásticas”, pero cuando una persona ve un símbolo ofensivo en un código QR, su reacción no va a cambiar según si ese píxel es de datos o de un patrón de timing. Las esquinas del finder son simplemente cuadrados; tampoco entiendo por qué habría que excluirlas del análisis. Mientras más lo examino, menos cuadra, así que sospecho que puede ser un resultado generado a la ligera por IA.
Me entristece que exista un proyecto como este. Ni siquiera se me había ocurrido que pudiera aparecer por casualidad un símbolo ofensivo dentro de un código QR.
Calculé directamente “¿qué tan seguido pasa que, al crear un código QR simple, aparece al azar un enorme símbolo nazi?”. Un código QR no es completamente aleatorio, pero aquí lo voy a ignorar.
Si miramos de forma independiente las esvásticas de 5×5 y 7×7, hay dos direcciones izquierda/derecha, dos polaridades y formas invertidas/normales, para un total de 8 patrones. El total de patrones posibles es 2^25 = 33 millones en 5×5 y 2^49 = 562 billones en 7×7, así que la probabilidad de que contengan una esvástica es de 2.38e-7 y 1.42e-14, respectivamente. Dentro de un código QR hay 289 regiones de 5×5 y 225 regiones de 7×7, por lo que la probabilidad total de que aparezca al menos una esvástica en una forma de código QR aleatoria es de aproximadamente 0.00006, es decir, 1 de cada 14,500. Se podría calcular también para 9×9 o más, pero la probabilidad de una combinación específica de píxeles es tan baja que no afecta de forma significativa el resultado. Lamentablemente, al ver el código fuente parece que este proyecto fue hecho con vibe coding, pero el cálculo lo hice a mano.
Siendo un proyecto tan específico, me da curiosidad si hay alguna historia de fondo o algún chiste detrás.
Dicho eso, viendo que se usan IA bastante defectuosas —por ejemplo, el hash perceptual de Microsoft photoDNA no maneja bien las cuadrículas de miniaturas de CSAM que abundan en los datos de entrenamiento y termina suspendiendo cuentas de usuarios de Discord solo por capturas de hojas de cálculo y cuadrículas de creación de Minecraft—, una herramienta más general para evitar patrones de riesgo sí parece bastante atractiva.
Hay que resolver problemas reales en vez de repetir problemas del pasado de una forma nueva. En el mundo hay demasiada gente excesivamente sensible a la que este tipo de proyecto le parecería interesante.
Aunque el objetivo sea evitar esvásticas en los patrones de datos, como la propia página web muestra el símbolo, me pregunto si eso podría ser ilegal en Alemania.
Según esa sentencia del Tribunal Federal de Justicia de Alemania, las esvásticas tachadas están permitidas, y las demás se presentan como ejemplos de los patrones que el código filtraría, así que parece poco probable que haya problemas.
https://en.wikipedia.org/wiki/Strafgesetzbuch_section_86a