Cómo iniciar Windows en Modo Seguro

Para obtener un tutorial más detallado sobre cómo iniciar Windows 10 en modo seguro, os dejo este tutorial en inglés: How to Start Windows 10 in Safe Mode with Networking

Básicamente los pasos a seguir son los siguientes:

  1. Pulsa las teclas Ctrl+Alt+Supr al mismo tiempo para entrar en la pantalla de seguridad de Windows.
  2. Mientras mantienes pulsada la tecla Mayúsculas, haz clic en el botón de encendido (botón de encendido de Windows 10) y luego haz clic en Reiniciar.
  3. Cuando Windows 10 se reinicie, estarás en la pantalla Elegir una opción. En esta pantalla, haga clic en el botón Solucionar problemas para acceder a las opciones de Solución de problemas.
  4. En la pantalla Solución de problemas, haga clic en el botón Opciones avanzadas para abrir la pantalla de opciones avanzadas.
  5. En la pantalla de Opciones avanzadas, haga clic en la opción Configuración de inicio. Se abrirá la pantalla Configuración de inicio.
  6. En la pantalla Configuración de inicio, haga clic en el botón Reiniciar. Windows se reiniciará.
  7. Tras el reinicio, aparecerá la pantalla Configuración de inicio. En esta pantalla debes pulsar la tecla número 5 de tu teclado para entrar en Modo seguro con funciones de red.
  8. Su ordenador se reiniciará. Una vez reiniciado, aparecerá un mensaje de inicio de sesión. Inicie sesión para acceder al Modo seguro con funciones de red.
Minientrada

¿No sabes crear grids con CSS? Esta web te enseña

La web CSS Grid Generator es una herramienta en línea diseñada para ayudar a los desarrolladores y diseñadores web a crear rápidamente diseños de cuadrículas (grids) utilizando CSS Grid Layout. CSS Grid es una técnica poderosa para crear layouts de sitios web, y esta herramienta simplifica el proceso al generar el código CSS necesario sin que tengas que escribirlo manualmente.

¿Para qué sirve CSS Grid Generator?

  1. Diseño Visual Intuitivo: Permite crear diseños de cuadrículas de manera visual, ajustando filas, columnas, espacios entre elementos (gaps), y otras propiedades directamente desde la interfaz gráfica.
  2. Generación Automática de Código CSS: A medida que ajustas el diseño visualmente, CSS Grid Generator genera automáticamente el código CSS correspondiente. Puedes copiar este código y pegarlo directamente en tu proyecto para implementar el layout.
  3. Personalización Rápida: Puedes experimentar con diferentes configuraciones de filas y columnas, añadiendo o eliminando elementos fácilmente, lo que facilita la exploración de distintos diseños sin tener que escribir o modificar manualmente el código CSS.
  4. Ahorro de Tiempo: Es especialmente útil para desarrolladores que quieren crear layouts complejos rápidamente, sin necesidad de memorizar la sintaxis completa de CSS Grid.

En resumen, CSS Grid Generator es una herramienta práctica que simplifica la creación de layouts en CSS Grid, permitiendo a los usuarios generar el código necesario de forma rápida y eficiente, lo que es ideal tanto para principiantes como para desarrolladores experimentados que buscan optimizar su flujo de trabajo.

Minientrada

Sherlock, el mejor detective de OSINT

En el vasto panorama de la ciberseguridad y el análisis forense, las herramientas especializadas desempeñan un papel crucial. Hoy os traigo, Sherlock Linux, una herramienta que destaca como una solución robusta diseñada para potenciar la seguridad y simplificar el análisis forense en sistemas basados en Linux.

¿Qué es Sherlock Linux?

Sherlock Linux es una distribución personalizada de Linux que integra una variedad de herramientas de ciberseguridad y análisis forense. Está diseñada para proporcionar a los profesionales de la seguridad un entorno optimizado para la detección de amenazas, análisis de incidentes y recuperación de datos.

Características

Suite de Herramientas de Seguridad: Incluye una amplia gama de herramientas de ciberseguridad preinstaladas, como escáneres de vulnerabilidades, analizadores de tráfico de red, y sistemas de detección de intrusiones.

Entorno de Análisis Forense: Ofrece herramientas especializadas para el análisis forense digital, permitiendo la recuperación y el examen de datos, así como la identificación de rastros de actividades maliciosas.

Interfaz Amigable: Aunque está repleta de funciones avanzadas, Sherlock Linux cuenta con una interfaz de usuario intuitiva que facilita su uso tanto para expertos como para principiantes en ciberseguridad.

Actualizaciones Regulares: La distribución se mantiene actualizada con las últimas herramientas y parches de seguridad, garantizando que los usuarios siempre tengan acceso a las soluciones más recientes y efectivas.

Podéis descargarlo en el siguiente enlace: https://www.sherlock-linux.org/

Guía de BASH para principiantes

Bash (Bourne Again Shell) es un lenguaje de shell basado en el Bourne Shell original, que fue distribuido con el V7 Unix en 1979 y se convirtió en el estándar para escribir scripts de shell.

En la actualidad, es el shell principal en la mayoría de las distribuciones de Linux, en macOS y, recientemente, ha sido habilitado para ejecutarse en Windows a través del WSL (Subsistema de Windows para Linux).

Operadores cadenas

CARÁCTER DESCRIPCIÓN
= es igual a
== es igual a
!= no es igual a
< es mayor que el orden alfabético ASCII
> es mayor que el orden alfabético ASCII
-z la cadena es nula (es decir, de longitud cero)
-norte la cadena no es nula (es decir, de longitud cero)

Operadores numéricos

CARÁCTER DESCRIPCIÓN
-eq es igual a
-ne no es igual a
-gt es mayor que
-ge es mayor o igual a
-lt es menor que
-le es menor o igual a
< es menor que – colocar entre paréntesis dobles
<= es menor o igual que (misma regla que la fila anterior)
> es mayor que (misma regla que la fila anterior)
>= es mayor o igual que (misma regla que la fila anterior)

Códigos de salida/error

CÓDIGO DE SALIDA NO. DESCRIPCIÓN
1 Catchall para errores generales
2 Mal uso de las funciones integradas del shell
126 El comando invocado no puede ejecutarse
127 Comando no encontrado
128 Argumento no válido para salir
128+n Señal de error fatal «n»
130 Script terminado por Control-C

Señales de control

COMBINACIÓN DE TECLAS DESCRIPCIÓN
Ctrl+C La señal de interrupción envía SIGINT al trabajo que se ejecuta en primer plano.
Ctrl+Y El carácter de suspensión retrasada. Provoca la detención de un proceso en ejecución cuando intenta leer la entrada del terminal. El control se devuelve al shell, el usuario puede poner en primer plano, en segundo plano o finalizar el proceso. La suspensión retrasada solo está disponible en sistemas operativos que admiten esta función.
Ctrl+Z La señal de suspensión envía un SIGTSTP a un programa en ejecución, deteniéndolo y devolviendo el control al shell.

Otras señales

NOMBRE NÚMERO ACCIÓN  DESCRIPCIÓN
SIGHUP 1 salida Cuelga
SIGINT 2 salida Interrumpe.
SIGQUIT 3 volcado de memoria En paz.
SIGILL 4 volcado de memoria Instrucción ilegal.
SIGTRAP 5 volcado de memoria Trampa de rastro.
SIGIOT 6 volcado de memoria Instrucción IOT.
SIGEMT 7 volcado de memoria Instrucción MT.
SIGFPE 8 volcado de memoria Excepción de punto flotante.
SIGKILL 9 exit Muertes (no se pueden atrapar ni ignorar).
SIGBUS 10 core dump Error de autobús.
SIGSEGV 11 core dump Violación de segmentación.
SIGSYS 12 core dump Mal argumento para la llamada al sistema.
SIGPIPE 13 salida Escribe en una pipa sin que nadie pueda leerlo.
SIGALRM 14 salida Despertador.
SIGTERM 15 salida Señal de terminación del software.

Permisos

CÓDIGO DESCRIPCIÓN
s setuid cuando está en la columna de usuario
s setgid cuando está en la columna del grupo
t sticky bit
0—— El derecho de acceso que debería tener este lugar no está concedido.
4—–r Se concede acceso de lectura a la categoría de usuario definida en este lugar.
2—–w Se concede permiso de escritura a la categoría de usuario definida en este lugar.
1—–x El permiso de ejecución se otorga a la categoría de usuario definida en este lugar.
u Permisos de usuario
g permisos de grupo
oh otros permisos

Archivos especiales

ARCHIVO INFORMACIÓN
/etc/profile Ejecutado automáticamente al iniciar sesión
~.bash_profile
———————
~/.bash_login
———————
~.profile
Lo que se encuentre primero se ejecuta al iniciar sesión.
~/.bashrc Es leído por todos los shells sin inicio de sesión.

Expresiones regulares

OPERADOR EFECTO
. Coincide con cualquier carácter individual.
? El ítem anterior es opcional y se igualará, como máximo, una vez.
* El elemento anterior coincidirá cero o más veces.
+ El elemento anterior coincidirá una o más veces
{N} El elemento anterior coincide exactamente N veces.
{N,} El elemento anterior coincide N o más veces.
{N,M} El elemento anterior coincide al menos N veces, pero no más de M veces.
Representa el rango si no es el primero o el último en una lista o el punto final de un rango en una lista.
^ Coincide con la cadena vacía al principio de una línea; también representa los caracteres que no están en el rango de una lista.
$ Coincide con la cadena vacía al final de una línea.
[aoeiAOEI] Coincide con 1 carácter cualquiera de la lista.
[^AOEIaoei] ¡Coincide con 1 carácter cualquiera, que no está en la lista!
[af] Coincide con 1 carácter cualquiera en el rango af

Comandos

BUILTIN DESCRIPCIÓN
: Equivalente a verdadero.
. Lee y ejecuta comandos desde un archivo designado en el shell actual.
[ Es sinónimo de prueba pero requiere un argumento final de ].
alias Define un alias para el comando especificado.
bg Reanuda un trabajo en modo de fondo.
bind Vincula una secuencia de teclado a una función o macro de línea de lectura.
break Sale de un bucle for, while, select o Until.
builtin Ejecuta el comando integrado del shell especificado.
caller Devuelve el contexto de cualquier llamada de subrutina activa.
case
cd Cambia el directorio actual al directorio especificado.
command Ejecuta el comando especificado sin la búsqueda normal del shell.
compgen Genera posibles coincidencias de finalización para la palabra especificada.
complete Muestra cómo se completarían las palabras especificadas.
comopt
continue Reanuda la siguiente iteración de un bucle for, while, select o Until.
declare Declara una variable o tipo de variable.
dirs Muestra una lista de los directorios recordados actualmente.
disown Elimina los trabajos especificados de la tabla de trabajos para el proceso.
echo Muestra la cadena especificada en STDOUT.
enable Habilita o deshabilita el comando de shell integrado especificado.
eval Concatena los argumentos especificados en un solo comando y ejecuta el comando.
exec Reemplaza el proceso de shell con el comando especificado.
exit Obliga al shell a salir con el estado de salida especificado.
export Establece las variables especificadas para que estén disponibles para los procesos de shell secundarios.
fc Selecciona una lista de comandos de la lista del historial.
fg Reanuda un trabajo en modo de primer plano.
getopts Analiza los parámetros posicionales especificados.
hash Encuentra y recuerda la ruta completa del comando especificado.
help Muestra un archivo de ayuda.
history Muestra el historial de comandos.
if Utilizado para ramificación.
jobs Enumera los trabajos activos.
kill Envía una señal del sistema al ID de proceso especificado (PID).
let Evalúa cada argumento en una expresión matemática.
local Crea una variable de alcance limitado en una función.
logout Sale de un shell de inicio de sesión.
mapfile
popd Elimina entradas de la pila de directorios.
printf Muestra texto usando cadenas formateadas.
pushd Agrega un directorio a la pila de directorios.
pwd Muestra el nombre de ruta del directorio de trabajo actual.
read Lee una línea de datos de STDIN y la asigna a una variable.
readonly Lee una línea de datos de STDIN y la asigna a una variable que no se puede cambiar.
return Obliga a una función a salir con un valor que puede ser recuperado por el script que la llama.
set Establece y muestra valores de variables de entorno y atributos de shell.
shift Gira los parámetros posicionales una posición hacia abajo.
shopt Alterna los valores de las variables que controlan el comportamiento opcional del shell.
source Lee y ejecuta comandos desde un archivo designado en el shell actual.
suspend Suspende la ejecución del shell hasta que se reciba una señal SIGCONT.
test Devuelve un estado de salida de 0 o 1 según la condición especificada.
times Muestra el tiempo acumulado de shell del sistema y del usuario.
trap Ejecuta el comando especificado si se recibe la señal del sistema especificada.
type Muestra cómo se interpretarían las palabras especificadas si se usaran como un comando.
typeset Declara una variable o tipo de variable.
ulimit Establece un límite en el recurso específico para los usuarios del sistema.
umask Establece permisos predeterminados para archivos y directorios recién creados.
unalias Elimina el alias especificado.
unset Elimina la variable de entorno o el atributo de shell especificado.
until Bucle que es muy similar al bucle while excepto que se ejecuta hasta que el comando de prueba se ejecuta con éxito. Mientras el comando de prueba falle, el ciclo hasta continúa.
wait Haga que el shell espere a que termine un trabajo.
while Espera a que se complete el proceso especificado y devuelve el estado de salida.

¿Cuál es la diferencia entre un Proceso y un Hilo?

Hoy os traigo una pregunta muy popular en una entrevista: ¿Cuál es la diferencia entre un Proceso y un Hilo?

Para entender bien la distinción, lo primero que tenemos que definir es lo que es un Programa. Un programa es un archivo ejecutable que contiene un conjunto de instrucciones que se almacenan en el disco. Un solo programa puede tener múltiples procesos asociados a él. Por ejemplo, Chrome crea procesos separados para cada pestaña abierta del navegador, pero todos y cada uno de los procesos pertenecen a Chrome.

Cuando un programa se carga en la memoria de un ordenador y comienza a ejecutarse, se convierte en un Proceso. El proceso recién activado requiere acceso a recursos esenciales como registros, un contador de programa y una pila de llamadas para operar.

En el contexto de un proceso en ejecución, un hilo representa la secuencia más pequeña de instrucciones que puede ser gestionada independientemente por el planificador del sistema operativo.

La relación entre un programa, un proceso y un hilo puede resumirse en tres pasos:

  1. Un programa comienza como un conjunto estático de instrucciones contenidas en un archivo ejecutable.
  2. Cuando se carga en memoria, el programa previamente inerte, se activa en uno o más procesos en ejecución.
  3. Después de que un proceso se inicializa, adquiere memoria y recursos del sistema operativo. Un único proceso puede subdividirse en uno o varios subprocesos si es necesario. Por ejemplo, Microsoft Word suele dedicar un hilo a tareas de corrección ortográfica y otro a insertar texto en un documento.

Existen varias diferencias clave entre los procesos y los hilos:

  • Los procesos tienden a ejecutarse independientemente unos de otros, mientras que los hilos existen dentro del contexto de un proceso padre.
  • Los procesos individuales no comparten el mismo espacio de memoria, mientras que los hilos que pertenecen al mismo proceso padre pueden acceder a la memoria compartida.
  • Los procesos requieren más sobrecarga para inicializarse y terminarse que los hilos. Son operaciones de peso pesado.
  • La transición entre procesos requiere un cambio de contexto más caro en comparación con la transición entre hilos.
  • La comunicación y el intercambio de datos puede ocurrir más rápido entre los hilos, ya que habitan en el mismo contexto de proceso.
Fuente: ByteByteGoFuente: ByteByteGo

Compilador en línea, depurador visual y tutor de inteligencia artificial

¿Te has preguntado alguna vez cómo se ejecuta realmente tu código? ¿Te gustaría ver visualmente cómo cambian las variables y estructuras de datos a medida que avanzas línea por línea? Python Tutor es la herramienta perfecta para ti.

Python Tutor es una plataforma educativa gratuita que te permite visualizar la ejecución de tu código Python (y otros lenguajes) de manera interactiva, facilitando la comprensión de conceptos complejos y el seguimiento del flujo de tu programa.

Entrando en su web, puedes encontrar un ejemplo de como funciona para que veas lo útil que puede llegar a ser. Este es el ejemplo:

Enlace: https://pythontutor.com/

Minientrada

Si tienes un Samsung te taigo un truco muy útil

Hoy a todos los que tenéis un Samsung os traigo una guía de como lograr transformar las imágenes de la galería en un sólo archivo PDF.

Para hacerlo el primer paso es ingresar a las opciones de galería y seleccionar la opción «acerca de la galería«. En el punto donde aparece la versión, pulsar varias veces seguidas hasta que aparezca el mensaje de que se ha activado (11 veces).

Volviendo a la configuración, aparecerá la opción Gallery Labs que es la nueva función que se ha activado. En ese menú debemos activar la opción «Save as PDF«.

Finalmente, ya solo te queda seleccionar las imágenes deseadas y en la opción «crear» aparecerá la opción «guardar como PDF«.

Ingeniería Social (Parte 3)

Tercera entrega de este grupo de artículos en el que os hablo de la ingeniería social, que es una de las amenazas más insidiosas en el ámbito de la ciberseguridad, explotando la confianza y la manipulación psicológica para acceder a información confidencial. Es crucial estar siempre alerta y educarnos sobre estas tácticas para no caer en sus trampas. Podéis leer antes la parte 1 (Enlace) y la parte 2 (Enlace).

Hoy os traigo una herramienta muy interesante para poder realizar este tipo de ataques.

SET

El Social Engineer Toolkit (SET) es una suite diseñada para la ingeniería social que permite automatizar diversas tareas. Con SET, puedes clonar cualquier página web y lanzar un servidor para hacer phishing en segundos, o generar un código QR que dirija a una URL específica o ejecute una applet maliciosa cuando se escanee.

SET integra muchas funciones de Metasploit, por lo que es necesario tener Metasploit instalado para usar SET. Utilizaremos la distribución Kali Linux, que viene con SET y Metasploit preinstalados. Para ejecutarlo, búscalo en el menú de Aplicaciones o escribe setoolkit en la línea de comandos.

Aquí os muestro un ejemplo de la herramienta en un terminal KALI. La pantalla principal nos proporciona diversas opciones para ejecutar: la primera consiste en diferentes ataques de ingeniería social, la segunda ataques de exploit como inyecciones de SQL, entre otros…. y la tercera módulos de ataque de terceras partes. El resto son opciones para actualizar la herramienta, ayuda, créditos…

Os voy a explicar algunos de los ataques de ingeniería social que nos ofrece la herramienta:

  • Spear-Phishing Attack Vectors: se utiliza para llevar a cabo ataques de correo electrónico dirigidos contra la víctima. Permite enviar emails de forma masiva o a un objetivo. También permite falsificar la dirección de email de emisor.
  • Infectious Media Generator: nos permite crear medios infectados, ya sea un USB, un CD o un DVD, con un archivo autorun.inf, con un payload de Metasploit que se ejecutará automáticamente si la opción de autorun está activada.
  • Create a Payload and Listener: crea un payload de Metasploit y un servidor a la escucha del payload.

Ofrece muchas más funciones (QRCode Generator Attack Vector, Website Attack Vectors, Third Party Modules, etc.) pero estas son las que me han parecido más interesantes.

Os dejo un vídeo, que aunque es antiguo y está algo desactualizado, nos sirve para entender SET. Enlace al vídeo

Conclusión

El Social Engineer Toolkit (SET) es una herramienta poderosa y versátil para llevar a cabo ataques de ingeniería social de manera eficiente. Su capacidad para automatizar tareas como la clonación de páginas web y la generación de códigos QR maliciosos lo convierte en un recurso valioso tanto para profesionales de la ciberseguridad como para aquellos que buscan comprender y mitigar este tipo de amenazas. Sin embargo, es crucial utilizarlo de manera ética y responsable, siempre con el objetivo de mejorar la seguridad y proteger la información. Con la distribución Kali Linux, que incluye ambas herramientas, SET se consolida como una herramienta esencial en el arsenal de ciberseguridad.

Ataque DDoS más grande de la Historia

El pasado 2 de octubre de 2024 se produjo el mayor ataque DDoS registrado hasta la fecha. Cloudflare confirmó que este ataue alcanzó un pico de 3.8 terabits por segundo (Tbps), superando a cualquier otro ataque de este tipo en la historia.

El objetivo de un ataque de denegación de servicio distribuido (DDoS) es denegar a los usuarios legítimos el acceso a un servicio. Para ello, los atacantes agotan los recursos que se necesitan para proporcionar el servicio. En el contexto de estos recientes ataques DDoS a las capas 3/4, ese recurso son los ciclos de CPU y el ancho de banda de la red.

Los autores del ataque aún son desconocidos, pero se cree que provienen de una red de dispositivos hackeados de difrentes partes del mundo. Este ataque fue parte de una campaña mayor que incluyó numerooso ataques DDo en un solo mes y con el pico en el indicado ataque de 3.8Tbps.

CloudFlare utilizó sus avanzados sistemas de protección contra DDoS para mitigar el ataque de manera automática. Estos sistemas detectaros y neutralizaron el ataque en 65 segundos, un tiempo record que evitó que causaran un daño significativo.

Como ya sabéis, este tipo de ataques puede dejar páginas webs fuera de servicio, causando péridas económicas importantes. Estas pérdidas son fáciles de entender con este ejemplo: «Imagina que eres el dueño de una tienda online que hace 100 ventas al día. Si recibes una ataque DDoS que impiden el acceso a potenciales compradores a tu web durante todo un día, perderías esas ventas. Si esto se repite varias veces al mes, el daño puede ser muy importante».

En el caso de CloudFlare los principales afectados fueron empresas de servicios financieros, telecomunicaciones e Internet. Este ataque demuestra la imporatacia de contar con sistemas de seguridad robustos y la importancia de tener la capacidad de responder rápidamente a amenazas cibernéticas.

En futuras entregas explicaremos en más profundidad este tipo de ataques.

Rarezas y cosas que no sabías de JavaScript – Parte 2

Hace un tiempo os traje una publicación en la que os mostraba algunas cosas curiosas que tiene el lenguaje JavaScript. Lo puedes ver en este enlace: «Rarezas y cosas que no sabías de JavaScript«.

Expresiones regulares

Vamos a comenzar hablando de algunos secretos en las expresiones regulares. Este en concreto, apareció en la versión 1.3.

El uso que se le suele dar a la función «replace()» suele ser algo de este estilo: alert('10 13 21 48 52'.replace(/d+/g, '*')); //reemplaza todos los números por *. Se trata de una forma simple de usarlo, pero ¿qué pasaría si quisiéramos tener más control? ¿Qué pasaría si, por ejemplo, quisiéramos reemplazar solo los números menores de 20? Necesitamos saltar a una función de devolución de llamada para evaluar cada coincidencia.

alert('10 13 21 48 52'.replace(/d+/g, function(match) { return parseInt(match) 20 ? '*' : match;}));

Para cada coincidencia realizada, JavaScript llama a nuestra función y pasa la coincidencia a nuestro argumento de coincidencia. Luego, devolvemos el asterisco (si el número coincidente es inferior a 20) o la coincidencia misma (es decir, no debería realizarse ninguna coincidencia).

Otra función que es desconocida por mucha gente es la función «test()». Seguro que has usado expresiones regulares para buscar coincidencias en cadenas de texto. Y seguro que las funciones que has utilizado son «match» y «replace«, ya que solo con esas dos ya resuelves una gran parte de tus problemas. La función «test» funciona igual que «match» pero en lugar de devolver la coincidencia, devuelve true o false en caso de que el patrón coincida o no lo haga. Ejemplo: /w{3,}/.test('Hello') –> devuelve ‘true’.

Finalmente destacar la función «RegExp» que permite utilizar expresiones regulares de forma dinámica, es decir, permite pasar una variable que contenga la expresión regular, en lugar de tener que declararla con la forma corta (entre barras diagonales, como en el ejemplo anterior).

function findWord(word, string) { var instancesOfWord = string.match(new RegExp('b'+word+'b', 'ig')); alert(instancesOfWord);}findWord('car', 'Carl went to buy a car but had forgotten his credit card.');

Debido a que se especifican como cadenas, no mediante sintaxis de barra diagonal, podemos usar variables para crear el patrón. Sin embargo, esto también significa que debemos aplicar doble escape a cualquier carácter especial, como hicimos con el carácter de límite de palabra.

Misceláneas

Este problema no es exclusivo de JavaScript; de hecho, es una peculiaridad común en la informática que afecta a muchos lenguajes. La salida que obtienes al hacer esto 0.1 + 0.2 es 0.30000000000000004.

Esto está relacionado con lo que se conoce como la precisión de las máquinas. Cuando JavaScript intenta ejecutar la operación anterior, convierte los valores a sus equivalentes binarios.

Aquí es donde surge el problema: el valor 0.1 no es exactamente 0.1, sino una aproximación binaria cercana. En resumen, tan pronto como ingresas estos valores, ya están destinados a perder algo de precisión. Quizás esperabas dos decimales simples, pero lo que obtienes es el resultado de una aritmética binaria de punto flotante. Es como intentar traducir tu texto al ruso pero recibirlo en bielorruso: parecidos, pero no iguales.

Hay más aspectos técnicos aquí, pero son complejos y exceden el alcance de este artículo.

Las soluciones a este problema son un tema frecuente en los foros de desarrollo. La elección de una solución depende del tipo de cálculos que estés realizando. Aunque no entraremos en detalle sobre los pros y contras de cada método, las opciones comunes incluyen:

  1. Convertir a enteros y hacer los cálculos antes de volver a convertir a decimales.
  2. Modificar la lógica para permitir un rango de valores en lugar de un resultado exacto.

Es decir, en lugar de hacer:

var num1 = 0.1, num2 = 0.2, shouldEqual = 0.3;
alert(num1 + num2 == shouldEqual); // false

Podías hacer:

alert(num1 + num2 > shouldEqual - 0.001 && num1 + num2 < shouldEqual + 0.001); // true

En esencia, estás verificando si la suma de 0.1 + 0.2 es aproximadamente 0.3, dentro de un margen de error de 0.001 a cada lado. El inconveniente es que, para cálculos que requieren alta precisión, esta aproximación podría no ser adecuada.

Algo indefinido se puede definir

Vamos a terminar con un caso curioso y aparentemente inofensivo. Aunque undefined tiene un significado especial en JavaScript y se utiliza para determinar si una variable no está definida, sorprendentemente, no es una palabra reservada. Esto significa que puedes reasignarla, lo cual puede llevar a comportamientos inesperados. Por ejemplo:

var someVar;
alert(someVar == undefined); // evalúa como true

Hasta aquí todo parece normal. Sin embargo, considera lo siguiente:

undefined = "¡Ya no soy undefined!";
var someVar;
alert(someVar == undefined); // evalúa como false

Como ves, al reasignar undefined, cambias su significado, lo que puede causar errores difíciles de detectar. Para evitar problemas como este, es recomendable no modificar undefined y siempre mantener buenas prácticas de codificación. Además, puedes consultar la lista de palabras reservadas de JavaScript en Mozilla para futuras referencias.