Skip to Content

No te olvides de visitar:

Programación PHP

Reto PHP II: Test de Primalidad

Encaramos la llegada de los primeros fríos invernales con un nuevo reto PHP, está vez se trata de obtener un algoritmo que nos diga (con 100% de seguridad, nada de probabilidades) si un número (sea cual sea el tamaño) es primo o no.

El reto consiste en crear una función a la que pasamos una cadena con un número, y nos devuelve true (en caso que sea primo) o false (en caso que no sea primo). Tened en cuenta que el número que le pasemos puede tener cualquier tamaño, así que ya podéis echar mano de las librerías que hay en php para manejo de grandes números.

En esta ocasión ganará el algoritmo que devuelva el resultado correcto en el menor tiempo posible (la batería de pruebas cubrirá números pequeños, grandes, etc...).

  • Fecha Límite: 1 de Diciembre

Suerte y al lío.

PD: No se pueden utilizar funciones que hagan el trabajo por nosotros, como por ejemplo "gmp_prob_prime" o "gmp_nextprime".

Resultados del Reto PHP I

Hola a todos, compañeros y amigos....después de un mes de intriga e incertidumbre, aquí llegamos con los resultados del 1º Reto PHP del Rincón de Tolito.

La participación ha sido bastante más alta de lo esperado...como podéis ver en los comentarios del reto (además de los que me lo habéis enviado al correo). Así que sin más preámbulos vamos a por los resultados.

PREMIO A LA BREVEDAD

Para Víctor con 63 caracteres:

function reto($n){for($i=$n;$i;$i--)($n%$i)||$a[]=$i;return$a;}

PREMIO A LA VELOCIDAD

Para Guti (al que quiero felicitar desde aquí por su blog, y por el algoritmo) con este algoritmo:

function reto($piNumero)
{
  $aRes=array($piNumero);
  for ($iDivisor=$piNumero>>1; $iDivisor>0; $iDivisor--)
  {
    if (!($piNumero % $iDivisor))
    {
      array_push($aRes, $iDivisor);
    }
  }
  return($aRes);
}

VERSIÓN PROPIA

Yo, aunque no participo en el concurso, he desarrollado un algoritmo que, aunque no es la panacea, si que mejora infinitamente el tiempo de respuesta (en números grandes la mejora es muy notable). Lo que hace es recorrer el bucle for entre 0 y la raíz del número, con lo cual nos ahorramos muchas pasadas por el bucle, aquí os dejo el algoritmo desarrollado:

function reto($x)
{
  $t=ceil(sqrt($x));
  if ($t*$t==$x)
    $d[]=$t;
  for ($n=1;$n<$t;$n++)
  {
    if (!($x%$n))
    {
      $d[]=$n;
      $d[]=$x/$n;        
    }
  }
  return $d;
}

Un saludo a todos

Nota: Guti ha enviado una versión que precalculaba las factorizaciones de todos los números indicados y los guardaba en un archivo (unos 500 Gb(para el rango de enteros de php) calcula él que ocuparía). Yo la verdad no tengo espacio en disco suficiente para probarlo (ni paciencia para generar el archivo que precalcula los datos), pero creo que la búsqueda de un número en un archivo de texto de 500 Gb no debe ser una cosa muy rápida.

Reto PHP I: Obtener los divisores de un número

Hoy desde "El Rincón de Tolito" inauguramos una nueva sección: "RETOS PHP", la idea es la siguiente: yo(podéis enviarme ideas para nuevos retos) propongo desde aquí un reto con sus condiciones, y vosotros vais enviándome vuestras soluciones en forma de comentario del post (los comentarios están moderados, y por tanto no aparecerán publicados hasta el final del concurso), o por correo electrónico (tolito(arroba)gmail(dot)com). Una vez terminado el plazo publicaré los códigos ganadores, así como sus autores. Así que vamos al lío con el primer reto:

RETO PHP I

Enunciado: Desarrollar una función llamada "reto" a la cual la pasemos un número (integer) y nos devuelva un array (divisor[0]=x....divisor[n]=y) con todos los divisores de dicho número, incluyendo el 1 y el propio número.

Códigos Ganadores: Hay 2 premios:

  • Código veloz: Después de una batería de pruebas(serán las mismas para todos) se verá cual es el código más rápido de todos los participantes.
  • Código breve: Este premio se lo llevará el código que menos ocupe, así que a abreviar...

Condiciones:

  • Las pruebas se llevarán a cabo en un servidor Ubuntu con Apache y PHP 5.2.5.
  • Cada usuario puede enviar 2 programas, así puede optar a los 2 premios a la vez, ya que es complicado que el mismo código gane los 2 premios, aunque nunca se sabe...
  • El envío debe incluir el nick del autor, una dirección de correo electrónico (no se hará publica para evitar spameos), y el código de la función.
  • Fecha límite para el envío de respuestas: 30 de Septiembre del 2009
  • El código que no funcione, o que de errores no será considerado valido. Puede dar warnings o notice siempre que funcione correctamente

¡Animo a todos y a optimizar código!

Actualización [28 Agosto 2009 - 14:41]: Ya hemos recibido los primeros programas...

Actualización [01 Septiembre 2009 - 10:50]: Siguen llegando programas, pero todos son para el premio de brevedad...a ver si alguien se anima a optimizar el código para mejorar su rendimiento.

Actualización [02 Septiembre 2009 -19:21]: En el premio a la brevedad solo se tendrá en cuenta la función, no os preocupeis de etiquetas php y demás historias...

Script PHP para obtener los enlaces de una página Web

Categoría:

Vamos a ver como gracias a la "DOM Extension" de PHP podemos extraer todos los enlaces de una página web con un sencillo script PHP, sin necesidad de complicarnos con expresiones regulares.

Aquí os dejo un ejemplo muy sencillo comentado para que veáis como funciona:

<?php
  //Decimos a libxml que no muestre errores
  $original_config = libxml_use_internal_errors(true);
  libxml_clear_errors();

  //Cargamos el archivo html
  $html = new DOMDocument();
  $html->loadHtmlFile('http://www.chungarratadas.com');

  //Usamos DOMXPath para buscar los enlaces (/a)
  $xpath = new DOMXPath($html); 
  $enlaces = $xpath->query('//a'); 

  //Recorremos todos los enlaces encontrados y mostramos la url(href)
  foreach ($enlaces as $enlace) 
  { 
    echo $enlace->getAttribute('href')."<br/>";
  } 

  //Devolvemos a su estado original el reporte de errores de libxml
  libxml_clear_errors(); 
  libxml_use_internal_errors($original_config); 

?>

Un saludo a todos!

Sencillo algoritmo en PHP para calcular la edad

Categoría:

Hoy vamos a ver un sencillo método para calcular la edad a partir de la fecha de nacimiento en PHP. Aquí os dejo un pequeño esbozo de como puede ser este sencillo algoritmo:

<?php
  $fechanacimiento = "13-01-1965";
  $anyonac = substr($fechanacimiento,6,4);
  $mesnac = substr($fechanacimiento,3,2);
  $dianac = substr($fechanacimiento,0,2);

  if ( ($mesnac < date("m")) || (($dianac <= date("d")) && ($mesnac==date("m"))) )
  { 
    //Si el último cumpleaños ya ha sido este año
    $edad = date("Y") - $anyonac;
  } 
  else 
  {
    //Si el último cumpleaños no ha sido aún este año le restamos 1 a la edad
    $edad= date("Y") - $anyonac - 1 ;
  }
  echo "La edad es: ".$edad;
?>

Un saludo!

Ocultar la URL de nuestras imagenes con PHP

Categoría:

Estos últimos días se ha hablado mucho de la falta de seguridad en redes sociales como Facebook o tuenti, debido a un problema con las imágenes. Resulta que si conocemos la URL de una imagen de algún usuario podemos acceder a esta imagen seamos o no amigos suyos (incluso sin ser usuarios del sistema).

Este problema que puede parecer tan "complicado de resolver", en realidad es una tontería que con un poco de PHP queda solucionado.

Para mostrar las imágenes lo que haremos será leerlas con readfile y enviarlas al buffer de salida (imagen.php):

<?php
if ((isset($_GET['id_img'])) and (is_numeric($_GET['id_img'])))
{
  if (comprobar_permisos($_GET['id_img']))
    $url=obtener_url('id_img');
  else
    $url='http://wwww.miweb.com/img/sinprivilegios.jpg';

  header("Content-type: image/jpg");
  readfile($url);
}

function comprobar_permisos($id_img)
{
  /* Comprobamos contra la base de datos que el usuario actual tiene permisos
     sobre la imagen que le pasamos, devolviendo true o false */
}

function obtener_url($id_img)
{
  // Se conecta a la base de datos y nos devuelve la url de la imagen
  return $url;
}
?>

Este sencillo script nos generara una imagen pero no mostrará la url de la misma, ya que siempre mostrará como url: http://www.miweb.com/imagen.php?id_img=xxx. Para mostrar la imagen solo tendremos que hacer lo siguiente:

<img src='http://www.miweb.com/imagen.php?id_img=xxx'>

Solo tenemos que Sustituir xxx por el id de la imagen que queramos mostrar. En la base de datos tendremos una tabla con los id's de las imágenes y sus urls correspondientes, así como otra tabla para guardar que usuarios tienen permisos sobre que imágenes.

Este sencillo método solucionaría de un plumazo el problema de la privacidad en tuenti o en facebook de una manera bastante sencilla.

Un saludo!

Fechas en castellano en PHP

Categoría:

Hace poco me estaba pegando con un código para lograr poner la fecha en castellano sin necesidad de andar con arrays que guardaran los días de la semana y los nombres de los meses, hasta que al fin encontré una solución al tema gracias a set_locale. Set_locale lo que hace es indicarle al interprete de PHP la información de localización que queremos utilizar. Aquí os dejo el código que utilice por si a alguien le puede resultar útil:

<?php
  set_locale(LC_ALL,"es_ES@euro","es_ES","esp");
  echo strftime("%A %d de %B del %Y");
?>

Con el set_locale le especificamos varias localizaciones por si no encuentra una que intente usar la siguiente. Y en la siguiente línea lo que hace es escribir la fecha con el formato: Martes 12 de Agosto del 2007

Hasta luego y espero que os resulte útil

Uso de die y exit para parar la ejecución de un script PHP

Categoría:

Hola a todos, he visto en algunos scripts que la gente para mostrar un error y después parar la ejecución de un programa utiliza echo + exit de la siguiente manera:

<?php
if (!mysql_connect('localhost'))
{
   echo 'Error al conectar a la base de datos';
   exit (0);
}
?>

Solo quería comentar que este código queda mucho más elegante usando en su lugar la instrucción die, que hace lo mismo que echo + exit:

<?php
if (!mysql_connect('localhost'))
{
  die ('Error al conectar a la base de datos');
}
?>

Solo quería hacer esta pequeña puntualización, un saludo!

Cómo ocultar la versión de PHP

Categoría:

Vamos a ver como podemos ocultar la versión de PHP de nuestro servidor, para así no dar más información de la necesaria a nuestros visitantes.

Si ponemos en el servidor la directiva "ServerTokens Prod" ocultará la versión de Apache y PHP en ciertas cabeceras y en los mensajes de error, pero la versión de PHP se puede seguir viendo en una de las cabeceras.

HEAD http://www.elrincondetolito.com
200 OK
Connection: close
Date: Fri, 16 Jun 2006 01:16:30 GMT
Server: Apache
Content-Type: text/html; charset=UTF-8
Client-Date: Fri, 01 Jan 2007 21:48:13 GMT
Client-Peer: 192.168.0.102:80
Client-Response-Num: 1
X-Powered-By: PHP/5.1.2-1+b1

Para ocultarlo vamos al fichero "php.ini", y ponemos a "off" la línea "expose_php = On". Esta línea viene activada en la mayoría de las distribuciones, y en las compilaciones de PHP.

Un saludo y espero que os resulte útil.

Comprobar si un puerto esta abierto con PHP

Categoría:

Con este pequeño código podemos comprobar si un puerto se encuentra abierto...las posibilidades que da son bastante grandes...analizadores de puertos a gran escala, buscadores de servidores web, mysql, ssh, etc... que cada uno lo use para lo que quiera, aquí os lo dejo:

<?
//Configuramos el dominio y puerto al que conectar
$dominio = "dominio.com";
$puerto = 80;

//Intentamos abrir una conexión al dominio y puertos seleccionados
$fp = @fsockopen($dominio,$puerto,$errno,$errstr,10);

//Comprobamos si la conexión se ha realizado
if(!$fp)
{
   echo "El puerto esta cerrado";
}
else
{
   echo "Puerto abierto y conexión realizada.";
   fclose($fp);
}
?>

Un saludo a todos!

Distribuir contenido