Autor: ciberkaos

  • Caso Práctico DS1: Análisis de Tráfico Web y Login con Wireshark (2)

    Caso Práctico DS1: Análisis de Tráfico Web y Login con Wireshark (2)

    Aprender a capturar y analizar tráfico de red con Wireshark, identificar credenciales transmitidas en claro, interpretar paquetes HTTP y localizar patrones que un pentester o analista usaría para detectar:

    • Credenciales expuestas
    • Cookies de sesión
    • Estructura de peticiones al servidor
    • Intentos de ataque (básico)
    • Fingerprinting indirecto del hosting

    1. Preparación del entorno

    1.1. Material necesario

    • Wireshark instalado
    • Navegador web
    • La URL de vuestra aplicación PHP en el hosting

    1.2. Configuración previa

    1. Abrir Wireshark
    2. Elegir la interfaz correcta:
      • En WiFi: suele ser wlan0 o similar
      • En cable: eth0
    3. Aplicad un filtro pre-captura opcional para no saturar: tcp port 80 or tcp port 443

    2. Captura del tráfico (la parte divertida)

    2.1. Comenzar la captura

    1. En Wireshark → seleccionad interfaz → botón azul Start capture.
    2. Dejad Wireshark escuchando en segundo plano.

    2.2. Generar tráfico real

    En vuestra aplicación PHP:

    1. Entrad en la página del login.
    2. Haced:
      • 1 intento fallido
      • 1 intento correcto
    3. Navegad un poco por el CRUD (listar, ver, editar).

    Esto genera tráfico muy fácil de reconocer.


    3. Filtrado y análisis del tráfico HTTP

    3.1. Filtrar solo HTTP

    En la barra de filtros de Wireshark:

    http
    

    Observad cómo aparecen las peticiones:

    • GET /login.php HTTP/1.1
    • POST /login.php HTTP/1.1
    • Peticiones a JS, CSS, etc.

    Entrega:

    • Captura del primer filtro HTTP mostrando al menos 8–10 paquetes.

    4. Análisis de un login (¡a por credenciales!)

    Vamos a buscar el POST del login.

    4.1. Filtro preciso del POST

    http.request.method == "POST"
    

    Seleccionad el paquete que corresponda a vuestro login.

    4.2. Abrir el contenido del POST

    En el panel inferior → Hypertext Transfer ProtocolForm-urlencoded.

    Deberíais ver algo como:

    username=juan
    password=1234
    

    (¡si la web no usa HTTPS y el hosting no lo fuerza!)

    4.3. Preguntas para entregar

    1. ¿El login viaja en claro o cifrado?
    2. Si viaja cifrado, ¿qué aparece en su lugar?
    3. Si viaja en claro, copiáis:
      • usuario
      • contraseña
      • parámetros adicionales

    💡 Esta parte impacta mucho: “Así de fácil es robar credenciales sin HTTPS.”


    5. Análisis de cookies y sesión

    5.1. Buscar cookies de sesión

    Filtro:

    http.set_cookie
    

    o:

    http.cookie
    

    Localizad:

    • PHPSESSID=xxxxxxx u otro identificador.

    5.2. Preguntas para entregar

    1. ¿La cookie tiene flags Secure, HttpOnly, SameSite?
    2. ¿Se envía en la misma petición del login?
    3. ¿Se reutiliza durante toda la sesión?
    4. ¿Podríais robarla si el tráfico no fuese HTTPS?

    6. Identificación de servidor y tecnologías mediante tráfico

    Aunque no usemos WhatWeb, Wireshark también revela cosas interesantes.

    6.1. Buscad cabeceras del servidor

    Filtro:

    http.server
    

    y:

    http.response
    

    Podéis encontrar:

    • Server: Apache/2.4.54
    • X-Powered-By: PHP/8.1.12

    7. Detectar patrones de ataque (mini-reto)

    Ahora vamos a “jugar” con el tráfico que vosotros mismos habéis generado.

    Hacer desde otra máquina:

    • un par de intentos de fuerza bruta
    • navegación rara
    • errores 404
    • probad rutas prohibidas

    7.1. Filtrar errores del servidor

    http.response.code >= 400
    

    7.2. Preguntas

    1. ¿Qué tipo de errores aparecen más?
    2. ¿Alguna IP destaca como “sospechosa”?
    3. ¿Puedes reconstruir qué intentaba hacer ese cliente?
      (por ejemplo: intentar acceder a /admin/ o /backup/)

    8. Bonus: reconstrucción de sesión (Follow TCP Stream)

    Seleccionad cualquier paquete HTTP → botón derecho:

    Follow → TCP Stream

    Miraréis la conversación completa entre cliente y servidor como si fuese un chat textual.

    Entrega:

    1. Captura del stream
    2. Comentad:
      • ¿Qué información sensible se ve?
      • ¿Podríais reproducir manualmente alguna petición?

    9. Conclusiones finales (informe corto)

    Cada alumno debe redactar:

    9.1. Hallazgos importantes

    • ¿Se ven credenciales?
    • ¿Se identifican cookies inseguras?
    • ¿Qué tecnologías se filtran?
    • ¿Alguna ruta interesante/extraña?

    9.2. Riesgos detectados

    3 riesgos mínimos (exposición de tecnología, falta de HTTPS, cookies inseguras…)

    9.3. Recomendaciones

    3 medidas de mejora:

    • Forzar HTTPS
    • Ocultar versión del servidor
    • Flag HttpOnly en cookies
    • Deshabilitar rutas innecesarias
  • Caso Práctico DS1: Fingerprinting y superficie de ataque (3)

    Caso Práctico DS1: Fingerprinting y superficie de ataque (3)

    enéis desplegada una pequeña aplicación PHP (CRUD + login) en un hosting compartido.

    En esta práctica vais a poneros en la piel de un analista de ciberseguridad que tiene permiso para auditar solo ese sitio web. El objetivo es:

    • Identificar tecnologías y versiones que usa la web (fingerprinting).
    • Descubrir rutas y ficheros interesantes (superficie de ataque).
    • Detectar posibles debilidades de configuración.

    ⚠️ Regla de oro: Solo podéis escanear el dominio/URL que os ha dado el profesor. Nada de escanear webs ajenas “por probar”.


    1. Preparación del entorno

    1.1. Datos que debes tener

    Anota en tu cuaderno o documento:

    • URL de la aplicación:
      Ejemplo: https://grupoX.miapp.ejemplo.com
    • (Opcional) IP del servidor si el profe la da:
      Ejemplo: 123.45.67.89

    1.2. Herramientas a usar

    En un Linux (real o máquina virtual) instalad, si no están:

    sudo apt update
    
    # WhatWeb (fingerprinting web)
    sudo apt install whatweb -y
    
    # Nikto (escáner de vulnerabilidades web)
    sudo apt install nikto -y
    
    # Gobuster (fuerza bruta de directorios)
    sudo apt install gobuster -y
    
    # Wordlist básica (si no la tenéis)
    sudo apt install wordlists -y
    

    Comprobad que funcionan:

    whatweb --version
    nikto -Version
    gobuster -h
    

    2. Fingerprinting básico del servidor web (WhatWeb + cabeceras)

    2.1. Resolver el dominio

    1. Desde la terminal, comprobad a qué IP resuelve vuestro dominio:
    ping -c 3 TU_DOMINIO
    

    Sustituye TU_DOMINIO por tu URL (sin https://).
    Ejemplo:

    ping -c 3 grupoX.miapp.ejemplo.com
    
    1. Anota:
      • IP a la que resuelve
      • Tiempo de respuesta aproximado

    Entrega: captura de pantalla o copia del comando y el resultado.


    2.2. Cabeceras HTTP con curl

    Queremos ver qué nos cuenta el servidor solo con las cabeceras.

    1. Ejecuta:
    curl -I https://TU_DOMINIO
    
    1. Fíjate en:
    • Server: (Apache, Nginx, etc., ¿con versión?)
    • X-Powered-By: (¿PHP con versión?)
    • Si hay algo como Set-Cookie:, etc.

    Entrega:

    • copia de las cabeceras
    • responde brevemente:
      • ¿Se está filtrando la versión exacta del servidor o PHP?

    2.3. Fingerprinting con WhatWeb

    Ahora usamos WhatWeb para identificar tecnologías:

    whatweb https://TU_DOMINIO
    

    Si quieres más detalle:

    whatweb -v https://TU_DOMINIO
    

    Analiza:

    • ¿Detecta CMS (WordPress, etc.)?
    • ¿Versiones de Apache/PHP?
    • ¿Librerías JS, frameworks?

    Entrega:

    • salida de WhatWeb (resumen)
    • lista de tecnologías detectadas
    • marca con un asterisco las que muestren versión concreta, ejemplo:
      • PHP 8.1.12 *
      • Apache 2.4.54 *

    3. Análisis de configuración con Nikto

    Nikto es un escáner de vulnerabilidades web orientado a configuración y ficheros por defecto.

    3.1. Lanzar un escaneo básico

    Ejecuta:

    nikto -h https://TU_DOMINIO
    

    Según el hosting puede tardar un poco.

    Mientras tanto, ve leyendo las líneas: muchas veces indican ficheros interesantes, redirecciones, opciones inseguras, etc.

    3.2. Interpretar resultados

    Cuando termine, revisa:

    • ¿Detecta archivos o directorios por defecto (ej: /phpinfo.php, /server-status, /test/)?
    • ¿Algún mensaje tipo “OSVDB”, “might be vulnerable to…”?
    • ¿Alguna recomendación de deshabilitar cosas?

    Entrega:

    1. Lista de 3–5 hallazgos relevantes de Nikto. Para cada uno:
      • Qué ha encontrado (ruta / mensaje).
      • Por qué podría ser un problema.
    2. Indica si crees que hay algo que debería deshabilitarse/eliminarse en el servidor.

    (Si el hosting está muy capado y Nikto no ve casi nada, eso también es un hallazgo: coméntalo.)


    4. Fuerza bruta de rutas y directorios con Gobuster

    Aquí empezamos a descubrir “piezas” ocultas de la aplicación: paneles, copias de seguridad, etc.

    4.1. Elección de wordlist

    Usaremos una wordlist relativamente pequeña para no machacar el hosting.

    Por ejemplo:

    ls /usr/share/wordlists/dirb/
    

    Una habitual:

    • /usr/share/wordlists/dirb/common.txt

    4.2. Lanzar Gobuster (modo dir)

    Comando base:

    gobuster dir \
      -u https://TU_DOMINIO \
      -w /usr/share/wordlists/dirb/common.txt \
      -t 30 \
      -x php,txt,html
    

    Explicación:

    • -u: URL objetivo
    • -w: wordlist
    • -t: hilos (no os flipéis, que es un hosting compartido)
    • -x: extensiones a probar (.php, .txt, .html)

    4.3. Analizar resultados

    Fíjate en entradas con códigos de estado interesantes:

    • 200 → existe y responde bien
    • 301/302 → redirecciones
    • 403 → existe pero está prohibido (¡ojo, puede haber algo interesante detrás!)

    Entrega:

    • Lista de rutas interesantes encontradas. Ejemplo:
      • /admin/ (200)
      • /backup/ (403)
      • /old/ (200)
    • Para cada una, explica:
      • ¿Crees que deberían ser accesibles?
      • ¿Podrían contener datos sensibles?

    5. Mini-conclusiones de seguridad

    Al final de la práctica, responde a estas preguntas en un pequeño informe (1–2 páginas):

    1. Fingerprinting
      • ¿Qué servidor web y versión usa vuestro hosting?
      • ¿Qué versión de PHP se expone (si es visible)?
      • ¿Se muestran cabeceras innecesarias (X-Powered-By, etc.)?
    2. Superficie de ataque
      • ¿Qué directorios ocultos/localizaciones interesantes habéis encontrado?
      • ¿Habéis visto algún archivo de configuración, backup, antiguo…?
    3. Riesgos
      • Señala al menos 3 riesgos potenciales que habéis identificado.
      • Para cada uno, describe:
        • Cómo lo habéis descubierto (herramienta + comando).
        • Qué podría hacer un atacante con ello.
    4. Recomendaciones
      • Escribe 3 medidas que propondrías al responsable del hosting:
        • Ejemplos: ocultar versión de servidor, borrar backups públicos, restringir /admin, etc.
  • Practica [OSINT]- SEÑALES DE VIDA (O ALGO PEOR) EN LA RED

    Practica [OSINT]- SEÑALES DE VIDA (O ALGO PEOR) EN LA RED

    Operación Nostromo: búsqueda de dispositivos comprometidos antes de que “algo” despierte…


    La nave USCSS Nostromo ha recibido una transmisión automática desde un sistema remoto. No se sabe si es una llamada de socorro… o una advertencia.
    La compañía ha encomendado al Equipo de Investigación (tus alumnos) usar Shodan para rastrear:

    1. Señales de dispositivos expuestos
    2. Orígenes de la transmisión
    3. Infraestructura del sistema remoto
    4. Posibles vectores de intrusión

    La misión: analizar patrones, encontrar conexiones y trazar el mapa de un “nido” digital escondido.

    La actividad se divide en 3 fases, cada una con un objetivo claro y un filtro de Shodan.

    FASE 1 — Localizar señales: “Ping de movimiento”

    Objetivo: practicar filtros por tipo de dispositivo + país/ciudad.

    El sensor de movimiento de la Nostromo detecta actividad anómala en una zona del sistema. Necesitamos saber qué dispositivos expuestos hay allí.

    Tareas:

    1. Buscar un tipo concreto de dispositivo (puerta automatizada, cámara IP, sistema industrial, etc.) Ejemplos:
      • Cámaras IP:
        product:GoAhead
        product:"Hikvision"
        port:554 has_screenshot:true
      • Paneles web expuestos:
        http.title:"login"
    2. Añadir filtro de ubicación (país o ciudad).
      Por ejemplo, España: country:ES product:GoAhead O por ciudad: city:Madrid http.title:login
    3. Apuntar IP, puerto, captura y versión como si fueran “señales biológicas”.


    FASE 2 — Identificar el origen de la transmisión

    Objetivo: buscar por organización o dominio.

    La señal parece provenir de una colonia (una empresa, universidad o dominio). Deben “explorar todas las instalaciones” de ese lugar.

    Ejercicios:

    1. Elegir una organización pública o conocida:
      Ejemplos: org:"Universidad Complutense" org:"Telefonica"
    2. Buscar todos los dispositivos de la misma entidad: hostname:"uic.es" hostname:"unizar.es"
    3. Revisar patrones:
      • ¿Qué puertos están abiertos?
      • ¿Qué servicios viejos aparecen?
      • ¿Hay dispositivos iguales repartidos por varias sedes?

    “Se detectan varias salas técnicas, ventilación, terminales…”
    Vamos, un nido perfecto para un xenomorfo.


    FASE 3 — Conexión entre señales: seguir el rastro del xenomorfo

    Objetivo: enlazar un dispositivo concreto → el resto del ecosistema.


    Han encontrado una máquina sospechosa que transmite paquetes extraños. La misión es identificar todo el entorno que la rodea.

    Cómo hacerlo:

    1. Selecciona un dispositivo que hayas encontrado en Fase 1.
    2. Observan:
      • dominio
      • ASN
      • organización
      • versión del servicio
    3. Construyen una nueva búsqueda:

      IP: 82.X.X.X
      org: "Ayuntamiento de ___"
      port 443 running nginx 1.18.0


      Entonces buscar:

      org:"Ayuntamiento de ___"
      product:"nginx"


      O incluso por ASN:

      asn:3352 (o el ASN que toque)

    4. Buscan patrones:
      • ¿Hay varios dispositivos vulnerables?
      • ¿Alguno tiene panel expuesto?
      • ¿Coinciden versiones?

    Misión Ash (ciencia sintética)

    Encontrar un dispositivo antiguo que no debería seguir activo:

    os:"Windows XP"
    

    o

    "Server: Apache/2.2"
    

    Misión Ripley: “Purgar la amenaza”

    Buscar servicios críticos abiertos sin autenticación:

    port:22 "OpenSSH_7"
    port:21 Anonymous
    

    Misión Bishop (android leal)

    Buscar paneles que tengan captura para analizar visualmente:

    has_screenshot:true city:Barcelona


    Registros:

    Informe breve estilo Weyland-Yutani
    (Ejemplo de redacción)

    • Recomendación para “contención”
    • Descripción de la amenaza detectada
    • Pruebas (capturas de Shodan)
    • Hipótesis del “nido” o red asociada

    (Ejemplo de redacción estilo Weyland-Yutani de la ficción de Alien)


    Alternativas interesantes a Shodan

    Herramienta / buscadorQué la hace útil / especialidad
    CensysEscanea infraestructura global, con foco extra en certificados SSL/TLS, puertos, hosts — útil para mapear superficie de ataque de forma sistemática. 5 Minute Breach+2We Live Security+2
    ZoomEyeSimilar a Shodan; ampliamente usada fuera del “mainstream” occidental. Puede servir para comparar visiones distintas del Internet expuesto. MarPoint+2SecurityVision.ru+2
    BinaryEdgePermite monitorear servicios, puertos abiertos, SSL, accesos remotos — y recibir alertas. Buena opción para vigilancia continua o auditorías periódicas. We Live Security+2LearnHub+2
    FofaOfrece sintaxis de búsqueda avanzada, lo que facilita búsquedas muy específicas (por puerto, servicio, sello de software, etc.). Puede servir bien para ejercicios dirigidos. We Live Security+1
    GreyNoiseNo es exactamente un “scanner” de dispositivos, sino más bien un filtro de ruido: ayuda a clasificar qué direcciones/IPs simplemente están haciendo escaneos automáticos masivos (ruido) frente a actividad potencialmente relevante. Útil para refinar resultados (filtrar falsos positivos). We Live Security+2LearnHub+2
    NetlasPlataforma más reciente, pensada para descubrimiento y monitorización global de “activos conectados”. Puede ser útil si buscas comparar con herramientas más consolidadas. SecurityVision.ru+2Netlas+2

    ⚠️ Cosas a tener en cuenta

    • Ninguna herramienta cubre todos los dispositivos — pueden faltar muchos servicios expuestos, por bloqueo, firewalls, NAT, técnicas de evasión.
    • Los datos recogidos (puertos, software, banners) pueden estar desactualizados o ser engañosos: muchas veces los sistemas cambian o los banners son falsos.
    • Uso de herramientas externas implica responsabilidad ética — incluso si lo haces con fines académicos, siempre debe mantenerse respeto por la privacidad y normas legales.
  • R3.1 – Programación-bucles

    R3.1 – Programación-bucles

    Ejercicio 1

    Contando del 1 al 10

    Crea un programa en Java que muestre por pantalla los números del 1 al 10 utilizando un bucle for.

    Requisitos:

    1. El programa debe tener una clase llamada Contador.
    2. Dentro del método main, utiliza un bucle for para recorrer los números del 1 al 10.
    3. En cada iteración, imprime el número actual en una nueva línea.

    Salida esperada:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    

    Ejercicio 2

    Cuenta atrás de 100 a 0 en pasos de 10

    Crea un programa en Java que haga una cuenta atrás desde 100 hasta 0, restando 10 en cada paso.

    Cuando llegue a 0, debe mostrar el mensaje «Máquina hackeada».

    Requisitos:

    1. El programa debe tener una clase llamada CuentaAtras10.
    2. Dentro del método main, usa un bucle for que empiece en 100 y vaya disminuyendo de 10 en 10 hasta llegar a 0.
    3. En cada iteración imprime el número actual.
    4. Al finalizar, muestra el texto Máquina hackeada.

    Salida esperada:

    100
    90
    80
    70
    60
    50
    40
    30
    20
    10
    0
    Máquina hackeada
    
    

    Ejercicio 3

    Realiza un algoritmo que simule una caja registradora de un supermercado, donde va pidiendo cantidades y las va sumando, cada vez que pongamos una cantidad por la terminal saldra la suma acumulada del total.

    El programa dejara de pedir las cantidades de compra cuando insertemos un 0.

    En ese momento mostrara el total de la compra y nos pedira que le indiquemos con cuanto dinero nos pagan e indicara el cambio que debemos devolver.

    Ejemplo de ejecución:

    Introduce la cantidad de la compra (0 para finalizar): 25.50
    Suma acumulada: 25.50
    Introduce la cantidad de la compra (0 para finalizar): 40.00
    Suma acumulada: 65.50
    Introduce la cantidad de la compra (0 para finalizar): 15.75
    Suma acumulada: 81.25
    Introduce la cantidad de la compra (0 para finalizar): 0
    Total a pagar: 81.25
    Con cuánto dinero te pagan? 100.00
    Cambio a devolver: 18.75
    

    Ejercicio 4

    Desarrollar un programa en Java que genere un dibujo usando únicamente el carácter asterisco (*). Este ejercicio te ayudará a entender mejor el control de bucles y el diseño de patrones en la consola.

    Descripción:

    Tu tarea es crear un programa que dibuje una pirámide de asteriscos. La altura de la pirámide será determinada por el usuario al inicio del programa.

    Requisitos:

    1. El programa debe pedir al usuario que introduzca un número entero positivo, el cual representará la altura de la pirámide.
    2. Utiliza bucles for o while para generar el patrón.
    3. La pirámide debe estar alineada a la izquierda, sin utilizar espacios para centrar las líneas.

    Ejemplo de salida:

    Si el usuario ingresa 5, el programa deberá mostrar el siguiente patrón:

    *
    **
    ***
    ****
    *****
    

    Ejercicio 5

    Crea un programa en Java que muestre el siguiente patrón usando dos bucles for anidados:

    Salida esperada:

    54321
    4321
    321
    21
    1
    
    

    Requisitos:

    1. Crea una clase llamada PatronDel5al1.
    2. Dentro del método main, utiliza un primer bucle for para controlar las filas, que empiece en 5 y termine en 1.
    3. Dentro de ese bucle, usa otro for que empiece en el valor de la fila y baje hasta 1.
    4. Después del bucle interno, imprime un salto de línea (System.out.println()).

  • R3.2 Programación-Bucles

    R3.2 Programación-Bucles

    Walter White y Jesse Pinkman han cocinado 1000 pastillas de «mentaanfetamienta» en su caravana.

    Cada pastilla tiene una calidad aleatoria entre 0 y 100.

    El “señor del pollo” (Gus Fring) solo acepta aquellas con calidad mayor o igual que 90.

    RETO 1: “El recuento del lote”

    Calcular cuántas pastillas tienen una calidad superior a 90.

    Pistas:

    • Usa Random para generar números del 0 al 100.
    • Usa un for para simular las 1000 pastillas.
    • Usa un contador para las “buenas”.

    Ejemplo de salida:

    Pastillas totales: 1000
    De calidad superior: 128
    

    RETO 2: “Hasta lograr la receta perfecta”

    Walter repite la cocción hasta que consiga una pastilla con calidad 100.

    Pistas:

    • Genera números aleatorios entre 0 y 100.
    • Detén el bucle cuando salga 100.
    • Muestra cuántos intentos necesitó.

    Ejemplo:

    ¡Perfecta! Calidad 100 obtenida tras 57 intentos.
    

    RETO 3: “La producción nocturna”

    Walter y Jesse producen pastillas hasta llegar a 1000 unidades buenas (≥90).

    Muestra cuántas totales han hecho (incluyendo las malas).

    Ejemplo:

    Para conseguir 1000 pastillas buenas, produjeron un total de 8732.
    

    RETO 4: “El análisis por lotes”

    Dividir la producción en 10 lotes de 100 pastillas y mostrar cuántas buenas hay en cada lote.

    Salida esperada:

    Lote 1 → 13 pastillas buenas
    Lote 2 → 8 pastillas buenas
    ...
    Lote 10 → 11 pastillas buenas
    
    

    RETO 5: “Promedio de calidad”

    Calcular el promedio total de calidad de las 1000 pastillas.

    Salida:

    Promedio de calidad general: 72.38
    
    

    RETO 6 (extra): “La inspección de Gus Fring”

    Genera pastillas hasta tener 500 buenas, pero cada vez que salgan 50 malas seguidas, muestra:

    🔥 Gus Fring sospecha del laboratorio...
    
    

    Ayuda:

    Chuleta Java – Math, Random y String


    🔹 Clase Math (no necesita crear objeto)

    Usa directamente: Math.metodo()

    MétodoDescripciónEjemploResultado
    Math.abs(x)Valor absolutoMath.abs(-5)5
    Math.max(a,b)Mayor de dos valoresMath.max(8,3)8
    Math.min(a,b)Menor de dos valoresMath.min(8,3)3
    Math.pow(a,b)Potencia (a^b)Math.pow(2,3)8.0
    Math.sqrt(x)Raíz cuadradaMath.sqrt(9)3.0
    Math.round(x)Redondea al entero más cercanoMath.round(3.6)4
    Math.floor(x)Redondea hacia abajoMath.floor(3.9)3.0
    Math.ceil(x)Redondea hacia arribaMath.ceil(3.1)4.0
    Math.random()Número aleatorio entre 0 y 1Math.random()0.0–0.999...
    Math.PIConstante πMath.PI3.14159…
    Math.EConstante eMath.E2.71828…

    Ejemplo práctico:

    double area = Math.PI * Math.pow(5, 2);
    
    

    🎲 Clase Random

    Primero importa y crea el objeto:

    import java.util.Random;
    Random r = new Random();
    
    
    MétodoDescripciónEjemploResultado
    r.nextInt(n)Entero entre 0 y n-1r.nextInt(10)0–9
    r.nextInt(max - min + 1) + minEntero entre min y maxr.nextInt(21) + 8080–100
    r.nextDouble()Decimal entre 0.0 y 1.0r.nextDouble()0.0–0.999...
    r.nextBoolean()Verdadero o falsor.nextBoolean()true / false

    Ejemplo:

    int dado = r.nextInt(6) + 1; // 1 a 6
    
    

    🧵 Clase String

    Recuerda: los String son objetos, y sus métodos se invocan sobre la variable:

    texto.metodo()

    MétodoDescripciónEjemploResultado
    length()Longitud del texto"Hola".length()4
    charAt(i)Carácter en posición i"Hola".charAt(1)'o'
    toUpperCase()Convierte a mayúsculas"hola".toUpperCase()"HOLA"
    toLowerCase()Convierte a minúsculas"HOLA".toLowerCase()"hola"
    equals(cadena)Compara textos (sensible a mayúsculas)"Hola".equals("hola")false
    equalsIgnoreCase(cadena)Compara ignorando mayúsculas/minúsculas"Hola".equalsIgnoreCase("hola")true
    substring(inicio, fin)Extrae parte del texto"Java".substring(1,3)"av"
    indexOf(cadena)Posición de una subcadena"Hola".indexOf("la")2
    contains(cadena)¿Contiene la subcadena?"Hola".contains("Ho")true
    startsWith(prefijo)¿Empieza por…?"Hola".startsWith("Ho")true
    endsWith(sufijo)¿Termina en…?"Hola".endsWith("la")true
    trim()Elimina espacios al inicio y final" Hola ".trim()"Hola"
    replace(a, b)Sustituye texto"Hola".replace("a","e")"Hole"

    Ejemplo combinado:

    String nombre = " Antonio ";
    System.out.println(nombre.trim().toUpperCase());
    
    

    ⚗️ Extra para curiosos

    Rango aleatorio con Math (sin Random):

    int n = (int)(Math.random() * 21) + 80; // 80–100
    
    
  • R3.3 – Arrays – Bienvenido al mundo de Mr. Robot

    R3.3 – Arrays – Bienvenido al mundo de Mr. Robot

    Evil Corp —el gigante que controla todo lo que consumes, lo que piensas y hasta lo que olvidas— cree tenerlo todo bajo control.

    Pero no contaba contigo.

    En un sótano lleno de cables, pantallas parpadeantes y tazas de café frías, un grupo de hackers conocidos como Atriumsociety prepara su próximo golpe digital. Su misión: devolver el poder a la gente, línea de código a línea de código.

    Tu papel comienza aquí.

    Eres parte del equipo. Hoy no vienes a “hacer ejercicios”, vienes a infiltrarte en el sistema, Cada array que declares es una base de datos secreta, cada bucle un intento de intrusión, cada condicional una decisión que puede cambiarlo todo.

    Prepárate: el prompt está parpadeando.

    Atriumsociety te necesita.

    1. “Elliot vs Evil Corp”

    Enunciado:

    Elliot ha interceptado una lista con los balances de Evil Corp.

    Con el siguiente array:

    int[] balances = {12000, -50, 5000, 15000, 0, -300, 800, 22000, 9999, 100};
    
    

    Muestra:

    • Cuántas cuentas tienen saldo negativo.
    • Cuántas tienen saldo superior a 10 000 $.
    • El saldo medio.

    2. “Backdoor Scanner”

    Enunciado:

    Darlene analiza si los servidores de Evil Corp están vulnerables.

    Usa el siguiente array:

    boolean[] vulnerables = {false, true, false, false, true, false, true, false};
    
    

    Muestra:

    • Cuántos servidores son vulnerables (true).
    • En qué posiciones están.

    3. “Password Audit”

    Enunciado:

    Elliot encuentra las siguientes contraseñas antiguas de Evil Corp:

    String[] passwords = {"admin123", "e@mpl3", "supersecure99", "pass", "root@2020"};
    
    

    Indica:

    • Cuántas contienen el carácter @.
    • Cuántas tienen más de 8 caracteres.
    • Cuántas terminan en un número.
    • Cuál es la más larga.

    4. “Hack the Gibson”

    Enunciado:

    Simula los niveles de éxito de los ataques de Elliot con el siguiente array:

    int[] intentos = {82, 13, 45, 79, 90, 5, 33, 72, 18, 65, 40, 100, 29, 10, 67, 55, 88, 60, 14, 3};
    
    

    Muestra:

    • El valor máximo y el mínimo.
    • Cuántos intentos fueron “exitosos” (más de 70).
    • Si todos son menores de 30, muestra “Mr Robot sospecha que estás desconectado”.

    5. “Logs del Servidor”

    Enunciado:

    Angela revisa los registros de acceso de un servidor:

    String[] logs = {"OK", "ERROR", "OK", "OK", "ERROR", "OK", "ERROR", "ERROR", "OK", "OK"};
    
    

    Cuenta:

    • Cuántos accesos fueron "OK".
    • Cuántos "ERROR".
    • Si hay más errores que accesos correctos, muestra “Servidor en peligro”.

    6. “Temperaturas del Servidor”

    Enunciado:

    Durante un ataque, Elliot monitoriza las temperaturas del servidor:

    int[] temperaturas = {45, 49, 52, 57, 60, 59, 55, 48, 46, 50};
    
    

    Calcula:

    • La temperatura media.
    • Cuántas mediciones superan los 55 °C.
    • Si todas las temperaturas están por debajo de 60 °C, muestra “Sistema estable”; si alguna es 60 o más, muestra “¡Sobrecalentamiento detectado!”.

    7. “DDoS Simulator”

    Enunciado:

    Durante un ataque DDoS, se registran los siguientes tiempos de respuesta (en ms):

    int[] tiempos = {200, 540, 720, 150, 950, 330, 480, 510, 870, 610};
    
    

    Muestra:

    • La media, el máximo y el mínimo.
    • Si más del 60 % supera los 500 ms, muestra “Servidor saturado”.
    • Si menos del 10 % supera los 200 ms, muestra “Ataque fallido”.
  • R6 – Clase PsicoHistoriador (Fundación)

    R6 – Clase PsicoHistoriador (Fundación)


    RETO 1: Clase PsicoHistoriador (Fundación)

    Contexto

    Formas parte del Proyecto Seldon, dentro del universo de Fundación. Vas a modelar a un psico-historiador, un especialista capaz de analizar el futuro del Imperio mediante matemáticas y sociología.

    Objetivo

    Crear una única clase en Java que represente a un psico-historiador. Este reto sirve para practicar atributos privados, constructores, getters, setters y métodos simples. No se permite utilizar listas, arrays, ni otras clases.

    Instrucciones

    1. Nombre de la clase
    La clase debe llamarse PsicoHistoriador.

    2. Atributos privados obligatorios

    Debes declarar:

    • String nombre;
    • int nivelMatematico; (0 a 100)
    • boolean lealtadFundacion;
    • int prediccionesRealizadas;

    3. Constructor
    El constructor debe recibir String nombre e int nivelMatematico.

    El resto se inicializa así:
    lealtadFundacion = true;
    prediccionesRealizadas = 0;

    4. Getters y setters
    Implementa métodos getter y setter para los atributos necesarios, al menos los siguientes:

    • getNombre()
    • getNivelMatematico() y setNivelMatematico(int n)
    • isLealtadFundacion() y setLealtadFundacion(boolean v)
    • getPrediccionesRealizadas()

    5. Método realizarPrediccion()
    Cada vez que se llame:

    • Aumenta en 1 prediccionesRealizadas.
    • Calcula una probabilidad usando nivelMatematico.
    • Devuelve un texto como:
      “El psico-historiador NOMBRE calcula una probabilidad de colapso del Imperio del X%.”

    6. Método evaluarRiesgoImperial()
    Debe devolver un mensaje según el valor de nivelMatematico:

    • Mayor de 80 → “Riesgo alto: el Imperio se derrumbará pronto.”
    • Entre 50 y 80 → “Riesgo moderado: el Plan Seldon sigue estable.”
    • Menor de 50 → “Riesgo bajo: estabilidad aparente, pero no te fíes.”

    7. Método main
    La misma clase debe contener un main que:

    • Cree un objeto PsicoHistoriador.
    • Llame a realizarPrediccion() varias veces e imprima el resultado.
    • Llame a evaluarRiesgoImperial() y muestre el mensaje final.

    RETO 2: Clase NaveEstelarFundacion (Constructores y Aleatoriedad)

    La Fundación mantiene una flota de naves estelares para explorar la galaxia. En este ejercicio practicarás atributos privados, varios constructores y el uso de un método auxiliar que genera valores aleatorios.

    Objetivo

    Crear la clase NaveEstelarFundacion implementando tres constructores, getters, setters, un método aleatorio proporcionado y un pequeño main de prueba. No se permite el uso de listas, arrays ni otras clases.

    Instrucciones

    1. Nombre de la clase
    La clase debe llamarse NaveEstelarFundacion.

    2. Atributos privados

    • String nombre;
    • String modelo;
    • int escudo;
    • int velocidadMaxima;
    • int misionesCompletadas;

    3. Método auxiliar ya proporcionado (NO modificar)

    private int generarAleatorio(int min, int max) { return (int)(Math.random() * (max - min + 1)) + min; } 

    4. Constructores obligatorios

    a) Constructor sin parámetros
    Debe asignar valores por defecto, por ejemplo:

    • nombre = "Anonima"
    • modelo = "Basico"
    • escudo = 50
    • velocidadMaxima = 2000
    • misionesCompletadas = 0

    b) Constructor con parámetros (nombre y modelo)
    Debe asignar los valores recibidos y generar:

    • escudo aleatorio entre 40 y 90
    • velocidadMaxima aleatoria entre 1500 y 4000
    • misionesCompletadas = 0

    c) Constructor con todos los atributos
    Debe recibir y asignar todos los campos: nombre, modelo, escudo, velocidadMaxima y misionesCompletadas.

    5. Getters y setters
    Debes implementar getters y setters para todos los atributos.

    6. Método desplegar()
    Devuelve un texto con los datos de la nave:

    "La nave NOMBRE, modelo MODELO, se despliega con escudo ESCUDO% y velocidad máxima VELOCIDAD km/s." 

    7. Método registrarMision()
    Aumenta en 1 el contador misionesCompletadas.

    8. Main de prueba
    Debe:

    Aumentar misiones con registrarMision() y mostrar el total.

    Crear una nave con el constructor por defecto.

    Crear otra con el constructor de dos parámetros.

    Crear una con el constructor completo.

    Llamar a desplegar() en cada una.

  • R7 – Guerra por el Sistema Solar: Tierra, Marte y el Cinturón” (The Expanse)

    R7 – Guerra por el Sistema Solar: Tierra, Marte y el Cinturón” (The Expanse)

    En el universo de The Expanse, la tensión entre la Tierra, Marte y el Cinturón ha acabado en guerra abierta. Tú vas a programar el sistema de gestión de una flota de naves que participan en esa guerra.

    El objetivo del ejercicio es trabajar:

    • Clases y objetos.
    • Uso de ArrayList con objetos.
    • Encapsulamiento y métodos.
    • Uso de Scanner para leer datos.
    • Un controlador con menú en consola.

    Deberás crear al menos tres clases:

    • Nave
    • Flota
    • Una clase con main (por ejemplo ControlFlota)

    1. Clase Nave

    Crea una clase Nave que represente una nave espacial.

    Atributos mínimos:

    • String nombre
    • String faccion
      (valores recomendados: "Tierra", "Marte", "Cinturon")
    • int misiles → número de misiles que tiene esa nave.
    • boolean necesitaReparacion → indica si la nave necesita pasar por dique seco.

    Requisitos:

    1. Al menos un constructor con todos los parámetros:
      • Nave(String nombre, String faccion, int misiles, boolean necesitaReparacion)
    2. Puedes añadir más constructores si quieres (por ejemplo, uno con menos parámetros).
    3. Métodos get y set para los atributos que consideres necesarios.
    4. Método toString() para mostrar la información de la nave de forma legible.

    2. Clase Flota

    La clase Flota representa un conjunto de naves en guerra.

    Atributo:

    • Un atributo privado:
      • ArrayList<Nave> naves;

    Requisitos de la clase Flota:

    1. Constructor sin parámetros
      Inicializa la lista:
      • Crea un ArrayList<Nave> vacío.
    2. Método para añadir una nave ya creada
      • void agregarNave(Nave nave)
        Añade la nave recibida como parámetro al ArrayList.
    3. Método para crear una nave usando Scanner y añadirla a la flota
      • void crearNaveDesdeTeclado(Scanner sc)
        Este método debe:
      • Pedir por teclado:
        • Nombre de la nave.
        • Facción (Tierra, Marte o Cinturon).
        • Número de misiles.
        • Si necesita reparación (por ejemplo, S/N).
      • Crear un objeto Nave con esos datos.
      • Añadir la nave creada a la lista de la flota.
    4. Método que devuelve el número de naves
      • int getNumeroNaves()
        Devuelve cuántas naves hay en la flota (tamaño del ArrayList).
    5. Método para listar todas las naves
      • void listarTodas()
        Muestra por pantalla todas las naves de la flota.
    6. Método para listar solo las naves que necesitan reparación
      • void listarNavesParaReparar()
        Recorre la lista y muestra solo las naves cuyo atributo necesitaReparacion sea true.
    7. Método para calcular el número total de misiles de la flota
      • int getTotalMisiles()
        Suma el número de misiles de todas las naves y devuelve el total.
    8. Método para listar naves por facción
      • void listarPorFaccion(String faccion)
        Muestra solo las naves cuya facción coincida con la indicada (por ejemplo "Tierra").
    9. Método para contar naves por facción
      • int contarPorFaccion(String faccion)
        Devuelve cuántas naves pertenecen a la facción indicada.

    Puedes añadir métodos auxiliares si lo necesitas (por ejemplo para validaciones).


    3. Clase ControlFlota (o similar) con main

    Crea una clase que contenga el método main y actúe como controlador.

    Requisitos:

    1. Crear un objeto Scanner y un objeto Flota.
    2. Opcionalmente, crear algunas naves iniciales por código (por ejemplo naves típicas de The Expanse) y añadirlas a la flota con agregarNave.
    3. Implementar un menú por consola que se repita hasta que el usuario elija salir (puedes usar while o do-while).

    El menú deberá tener, como mínimo, estas opciones:

    1. Añadir nave pidiendo datos por teclado
      • Llamar a crearNaveDesdeTeclado(sc).
    2. Añadir nave creada en el main
      • Crear un objeto Nave directamente en el main (con valores que tú pongas) y añadirlo a la flota con agregarNave.
    3. Listar todas las naves
      • Llamar a listarTodas().
    4. Listar naves que necesitan reparación
      • Llamar a listarNavesParaReparar().
    5. Mostrar número total de naves
      • Llamar a getNumeroNaves() y mostrar el resultado.
    6. Mostrar número total de misiles de la flota
      • Llamar a getTotalMisiles() y mostrar el resultado.
    7. Listar naves por facción
      • Pedir al usuario una facción (Tierra, Marte o Cinturon) y llamar a listarPorFaccion(faccion).
    8. Mostrar cuántas naves hay de una facción
      • Pedir al usuario una facción y llamar a contarPorFaccion(faccion).
      • Mostrar el resultado.
    9. Salir del programa.

    Cada opción debe ejecutarse según el número introducido por el usuario, y después de ejecutar la acción, el menú se volverá a mostrar hasta que el usuario elija la opción 0.


    4. Información extra The Expanse

    • La facción Tierra representa a la ONU y su flota clásica.
    • La facción Marte representa a la MCRN, con naves militares muy avanzadas.
    • La facción Cinturon representa a la OPA y a los belters, normalmente con naves reutilizadas o modificadas.

    Puedes usar nombres de naves inspirados en la serie (por ejemplo, “Rocinante”, “Donnager”, “Agatha King”, “Nauvoo”, etc.) o inventarte los tuyos, siempre dentro del contexto de la guerra entre Tierra, Marte y el Cinturón.


    Ejemplo Controlador MAIN

    Código del ControlFlota (main)

    import java.util.Scanner;
    
    public class ControlFlota {
    
        public static void main(String[] args) {
    
            Scanner sc = new Scanner(System.in);
            Flota flota = new Flota();
    
            // Naves iniciales opcionales (The Expanse vibes)
            flota.agregarNave(new Nave("Rocinante", "Cinturon", 24, false));
            flota.agregarNave(new Nave("Donnager", "Marte", 60, true));
            flota.agregarNave(new Nave("Agatha King", "Tierra", 40, true));
    
            int opcion;
    
            do {
                mostrarMenu();
                opcion = leerEnteroSeguro(sc);
    
                switch (opcion) {
    
                    case 1:
                        // Crear nave con Scanner
                        flota.crearNaveDesdeTeclado(sc);
                        break;
    
                    case 2:
                        // Crear nave desde el propio main
                        Nave n = new Nave("Nauvoo", "Cinturon", 80, false);
                        flota.agregarNave(n);
                        System.out.println("Nave creada desde main y añadida: " + n);
                        break;
    
                    case 3:
                        flota.listarTodas();
                        break;
    
                    case 4:
                        flota.listarNavesParaReparar();
                        break;
    
                    case 5:
                        System.out.println("Número total de naves: " + flota.getNumeroNaves());
                        break;
    
                    case 6:
                        System.out.println("Misiles totales en la flota: " + flota.getTotalMisiles());
                        break;
    
                    case 7:
                        System.out.print("Introduce la facción (Tierra/Marte/Cinturon): ");
                        String fac = sc.nextLine();
                        flota.listarPorFaccion(fac);
                        break;
    
                    case 8:
                        System.out.print("Introduce la facción (Tierra/Marte/Cinturon): ");
                        String fac2 = sc.nextLine();
                        int num = flota.contarPorFaccion(fac2);
                        System.out.println("Número de naves de la facción " + fac2 + ": " + num);
                        break;
    
                    case 0:
                        System.out.println("Saliendo del sistema de control de flota...");
                        break;
    
                    default:
                        System.out.println("Opción no válida.");
                }
    
                System.out.println();
    
            } while (opcion != 0);
    
            sc.close();
        }
    
        // -------------------------
        // Métodos auxiliares
        // -------------------------
    
        private static void mostrarMenu() {
            System.out.println("=== CONTROL DE FLOTA - GUERRA DEL SISTEMA SOLAR ===");
            System.out.println("1. Añadir nave (datos por teclado)");
            System.out.println("2. Añadir nave (creada en el main)");
            System.out.println("3. Listar todas las naves");
            System.out.println("4. Listar naves que necesitan reparación");
            System.out.println("5. Mostrar número total de naves");
            System.out.println("6. Mostrar número total de misiles");
            System.out.println("7. Listar naves por facción");
            System.out.println("8. Contar naves por facción");
            System.out.println("0. Salir");
            System.out.print("Elige una opción: ");
        }
    
        private static int leerEnteroSeguro(Scanner sc) {
            while (true) {
                try {
                    int valor = Integer.parseInt(sc.nextLine());
                    return valor;
                } catch (NumberFormatException e) {
                    System.out.print("Introduce un número válido: ");
                }
            }
        }
    }
    

  • R8 – El Escalafón Mágico de Hogwarts

    R8 – El Escalafón Mágico de Hogwarts

    El Ministerio de Magia ha implantado un nuevo sistema de clasificación de magos para evaluar su progreso, capacidades y responsabilidades dentro del mundo mágico.

    Tu misión será desarrollar, en Java, un pequeño sistema que represente este escalafón utilizando herencia entre clases, donde cada rango mágico añade nuevas habilidades y comportamientos.

    ⚠️ Importante

    Usar una enumeración (enum) para representar las Casas de Hogwarts.

    En este ejercicio NO se deben usar:

    • Métodos abstractos
    • Polimorfismo como concepto principal
    • Interfaces

    Diagrama de clases

    1 – Enumeración de Casas

    Crea una enumeración llamada Casa con las siguientes opciones:

    • GRYFFINDOR
    • SLYTHERIN
    • RAVENCLAW
    • HUFFLEPUFF

    Cada mago pertenecerá a una casa, y esta afectará a sus atributos iniciales.


    2 – Clase base Mago

    Crea la clase Mago, que será la base de todos los personajes mágicos.

    Atributos

    • nombre
    • nivel (1–100)
    • vida (0–100)
    • mana (0–100)
    • casa (tipo Casa)

    Comportamiento

    • entrenar()
      Aumenta el nivel y consume algo de vida y mana.
    • descansar()
      Recupera vida y mana.
    • ficha()
      Devuelve una cadena con los datos del mago.
    • lanzarHechizo(String hechizo)
      Método general que devuelve el daño causado (por defecto, bajo o 0).

    Al crear un mago, se aplicará un bonus inicial según su casa.


    3 – Rangos mágicos (herencia)

    Aprendiz (hereda de Mago)

    Representa a los alumnos más jóvenes de Hogwarts.

    Atributo extra

    • torpeza (probabilidad de fallo)

    Métodos

    • practicarBasico() → reduce torpeza

    Comportamiento

    • Puede lanzar hechizos básicos (Lumos, Alohomora)
    • Tiene posibilidad de fallar según su torpeza

    Hechicero (hereda de Aprendiz)

    Magos con formación avanzada.

    Atributo extra

    • controlVarita

    Métodos

    • estudiarEnBiblioteca() → mejora control y nivel

    Comportamiento

    • Acceso a hechizos más potentes (Expelliarmus, Stupefy)
    • Menos fallos y más daño

    Auror (hereda de Hechicero)

    Magos especializados en combate y seguridad mágica.

    Atributos extra

    • experienciaCombate
    • arrestos

    Métodos

    • patrullar() → mejora experiencia
    • arrestar(Aprendiz objetivo) → solo si el objetivo está débil

    Comportamiento

    • Hechizos más efectivos en combate
    • Puede usar hechizos defensivos

    Profesor (hereda de Hechicero)

    Magos con rol docente en Hogwarts.

    Atributos extra

    • asignatura
    • prestigio

    Métodos

    • enseñar(Aprendiz alumno) → mejora al alumno
    • evaluar() → aumenta prestigio

    Comportamiento

    • Hechizos más controlados
    • Menor consumo de mana

    4 – Programa principal

    Crea una clase Main que:

    • Cree al menos:
      • 2 Aprendices
      • 2 Hechiceros
      • 1 Auror
      • 1 Profesor
    • Muestre la ficha de cada personaje.
    • Ejecute varias acciones:
      • Lanzar hechizos
      • Entrenar / descansar
      • Enseñar, patrullar o arrestar según el rango

    Cada variable debe declararse con su tipo concreto
    (no usar listas genéricas de Mago).




    El conocimiento es poder… pero en Hogwarts, también lo es la herencia bien diseñada.

  • R3.1 [Solución] – Programación-bucles

    R3.1 [Solución] – Programación-bucles

    Ejercicio 1

    Contando del 1 al 10

    Crea un programa en Java que muestre por pantalla los números del 1 al 10 utilizando un bucle for.

    Requisitos:

    1. El programa debe tener una clase llamada Contador.
    2. Dentro del método main, utiliza un bucle for para recorrer los números del 1 al 10.
    3. En cada iteración, imprime el número actual en una nueva línea.

    Salida esperada:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    

    Idea clave

    Usamos un bucle for cuando conocemos de antemano cuántas veces queremos repetir algo.
    Aquí queremos mostrar los números del 1 al 10, ni más ni menos.

    Lógica

    • Inicializamos el contador en 1
    • Mientras sea menor o igual que 10
    • En cada vuelta lo incrementamos en 1

    Código solución

    
    
    
    
    
    public class Contador {
    
        public static void main(String[] args) {
    
            for (int i = 1; i <= 10; i++) {
                System.out.println(i);
            }
    
        }
    }
    

    🔍 Explicación línea a línea

    • int i = 1 → valor inicial
    • i <= 10 → condición para seguir iterando
    • i++ → incremento en cada vuelta
    • System.out.println(i) → muestra el valor actual


    Ejercicio 2

    Cuenta atrás de 100 a 0 en pasos de 10

    Crea un programa en Java que haga una cuenta atrás desde 100 hasta 0, restando 10 en cada paso.

    Cuando llegue a 0, debe mostrar el mensaje «Máquina hackeada».

    Requisitos:

    1. El programa debe tener una clase llamada CuentaAtras10.
    2. Dentro del método main, usa un bucle for que empiece en 100 y vaya disminuyendo de 10 en 10 hasta llegar a 0.
    3. En cada iteración imprime el número actual.
    4. Al finalizar, muestra el texto Máquina hackeada.

    Salida esperada:

    100
    90
    80
    70
    60
    50
    40
    30
    20
    10
    0
    Máquina hackeada
    
    

    Idea clave

    Un for también sirve para contar hacia atrás si modificamos correctamente el incremento (en este caso, decremento).

    Lógica

    • Empezamos en 100
    • Vamos restando 10 en cada iteración
    • Cuando termina el bucle, mostramos el mensaje final

    Código solución

    
    
    
    
    
    public class CuentaAtras10 {
    
        public static void main(String[] args) {
    
            for (int i = 100; i >= 0; i -= 10) {
                System.out.println(i);
            }
    
            System.out.println("Máquina hackeada");
        }
    }
    

    Detalles importantes

    • i -= 10 → resta 10 en cada vuelta
    • El mensaje no va dentro del bucle, para que se muestre solo una vez


    Ejercicio 3

    Realiza un algoritmo que simule una caja registradora de un supermercado, donde va pidiendo cantidades y las va sumando, cada vez que pongamos una cantidad por la terminal saldra la suma acumulada del total.

    El programa dejara de pedir las cantidades de compra cuando insertemos un 0.

    En ese momento mostrara el total de la compra y nos pedira que le indiquemos con cuanto dinero nos pagan e indicara el cambio que debemos devolver.

    Ejemplo de ejecución:

    Introduce la cantidad de la compra (0 para finalizar): 25.50
    Suma acumulada: 25.50
    Introduce la cantidad de la compra (0 para finalizar): 40.00
    Suma acumulada: 65.50
    Introduce la cantidad de la compra (0 para finalizar): 15.75
    Suma acumulada: 81.25
    Introduce la cantidad de la compra (0 para finalizar): 0
    Total a pagar: 81.25
    Con cuánto dinero te pagan? 100.00
    Cambio a devolver: 18.75
    

    Idea clave

    Aquí necesitamos:

    • Repetir hasta que el usuario introduzca 0
    • Ir sumando cantidades
    • Pedir un pago final y calcular el cambio

    Este es un caso perfecto para un bucle while.

    Lógica

    1. Pedimos cantidades hasta que llegue un 0
    2. Mostramos la suma acumulada
    3. Mostramos el total
    4. Pedimos el dinero entregado
    5. Calculamos el cambio

    Código solución

    
    
    
    
    
    import java.util.Scanner;
    
    public class CajaRegistradora {
    
        public static void main(String[] args) {
    
            Scanner sc = new Scanner(System.in);
            double total = 0;
            double cantidad;
    
            do {
                System.out.print("Introduce la cantidad de la compra (0 para finalizar): ");
                cantidad = sc.nextDouble();
    
                if (cantidad != 0) {
                    total += cantidad;
                    System.out.println("Suma acumulada: " + total);
                }
    
            } while (cantidad != 0); // Direfente es ( ! = )
    
            System.out.println("Total a pagar: " + total);
    
            System.out.print("Con cuánto dinero te pagan? ");
            double pago = sc.nextDouble();
    
            double cambio = pago - total;
            System.out.println("Cambio a devolver: " + cambio);
    
            sc.close();
        }
    }
    

    Conceptos trabajados

    • do-while → asegura al menos una ejecución
    • Acumulador (total)
    • Uso de double para cantidades con decimales
    • Entrada de datos con Scanner

    Ejercicio 4

    Desarrollar un programa en Java que genere un dibujo usando únicamente el carácter asterisco (*). Este ejercicio te ayudará a entender mejor el control de bucles y el diseño de patrones en la consola.

    Descripción:

    Tu tarea es crear un programa que dibuje una pirámide de asteriscos. La altura de la pirámide será determinada por el usuario al inicio del programa.

    Requisitos:

    1. El programa debe pedir al usuario que introduzca un número entero positivo, el cual representará la altura de la pirámide.
    2. Utiliza bucles for o while para generar el patrón.
    3. La pirámide debe estar alineada a la izquierda, sin utilizar espacios para centrar las líneas.

    Ejemplo de salida:

    Si el usuario ingresa 5, el programa deberá mostrar el siguiente patrón:

    *
    **
    ***
    ****
    *****
    

    Idea clave

    Cada línea imprime un número creciente de asteriscos.
    El número de líneas lo decide el usuario.

    Lógica

    • Un bucle controla las filas
    • Otro bucle imprime los * en cada fila

    Código solución

    
    
    
    
    
    import java.util.Scanner;
    
    public class Piramide {
    
        public static void main(String[] args) {
    
            Scanner sc = new Scanner(System.in);
    
            System.out.print("Introduce la altura de la pirámide: ");
            int altura = sc.nextInt();
    
            for (int i = 1; i <= altura; i++) {
                for (int j = 1; j <= i; j++) {
                    System.out.print("*");
                }
                System.out.println();
            }
    
            sc.close();
        }
    }
    

    Si i = 3, el bucle interno imprime:

    
    
    
    
    
    ***
    

    Cada fila tiene tantos asteriscos como el número de la fila.


    Ejercicio 5

    Crea un programa en Java que muestre el siguiente patrón usando dos bucles for anidados:

    Salida esperada:

    54321
    4321
    321
    21
    1
    
    

    Requisitos:

    1. Crea una clase llamada PatronDel5al1.
    2. Dentro del método main, utiliza un primer bucle for para controlar las filas, que empiece en 5 y termine en 1.
    3. Dentro de ese bucle, usa otro for que empiece en el valor de la fila y baje hasta 1.
    4. Después del bucle interno, imprime un salto de línea (System.out.println()).

    Idea clave

    Este ejercicio refuerza el concepto de bucles anidados descendentes.

    Lógica

    • El bucle externo controla las filas (de 5 a 1)
    • El bucle interno imprime los números desde la fila hasta 1

    Código solución

    
    
    
    
    
    public class PatronDel5al1 {
    
        public static void main(String[] args) {
    
            for (int i = 5; i >= 1; i--) {
                for (int j = i; j >= 1; j--) {
                    System.out.print(j);
                }
                System.out.println();
            }
    
        }
    }
    

    Qué ocurre aquí

    Y así hasta llegar a 1

    Primera fila: i = 5 → imprime 54321

    Segunda fila: i = 4 → imprime 4321