Tag Archives: code

Vim scripting con Python

Vim permite agregar funcionalidades mediante varios lenguajes externos, entre ellos Perl, Python, Ruby y Tcl. Para poder hacer uso de esta característica es necesario haber compilado Vim con el soporte para el lenguaje necesario (con el flag-python, para soporte python). En debian existe un paquete llamado vim-nox (no X) que contiene una versión compilada con soporte para los cuatro lenguajes mencionados:

sudo apt-get install vim-nox

Para comprobar que efectivamente se encuentre habilitado el soporte para Python ejecutar Vim y en modo comando escribir:

:echo has("python")

Un 1 indica que Vim interpreta Python ;)

Es muy recomendable leer la ayuda en línea:

:help python

También se puede acceder vía web desde http://vimdoc.sourceforge.net/htmldoc/if_pyth.html

Ejecución de código Python

La ejecución de una línea de código Python se realiza según la sintaxis:

:[range]py[thon] {stmt}

Ejemplo:

:python print "hello world"

Aquí el prompt mostrará el mensaje “hello world”.

En cambio para escribir código en varias líneas hay que usar la siguiente forma:

[range]:py[thon] < < {endmarker}
{script}
{endmarker}

Ejemplo:

:python < < EOF
def get_user():
  import os
  return os.getenv('USER')
EOF

De esta manera la función queda guardada en la memoria de la sesión actual. Luego su uso podría ser el siguiente:

:py user = get_user()

Tambien es posible cargar y/o ejecutar código desde un archivo externo. La sintaxis es:

:[range]pyf[ile] {file}

Ejemplo:

:pyfile myscript.py

Simyscript.pynecesitara parámetros la forma de pasárselos es la siguiente:

:py import sys
:py sys.argv = ['foo', 'bar']
:pyf myscript.py

El módulo vim

La comunicación entre Python y Vim se realiza a través del módulo vim, el cual hay que importar antes de usar:

:python import vim

Como indica la ayuda de Vim, el módulo implementa dos métodos (vim.command(str)yvim.eval(str)), tres constantes (vim.buffers,vim.windowsyvim.current) y un objeto error (vim.error). Las tres constantes mencionadas no son realmente constantes sino variables que pueden ser reasignadas pero, como dice también la ayuda, esto sería absurdo ya que se perdería acceso a los objetos de Vim que referencian. Por otra parte cabe recordar que no existen constantes en Python. Como cita el libro "Inmersión en Python":

Todo puede cambiar si lo intenta con ahínco. Esto se ajusta a uno de los principios básicos de Python: los comportamientos inadecuados sólo deben desaconsejarse, no prohibirse.


Read more »

Tags: , ,

Humor en comentarios de códigos fuente

Visto en stackoverflow.com

Algunos de ellos:

// sometimes I believe compiler ignores
// all my comments
// When I wrote this, only God and I understood
// what I was doing. Now, God only knows
if (/*you*/ $_GET['action']) { //celebrate
//
// Dear maintainer:
//
// Once you are done trying to 'optimize'
// this routine, and have realized what
// a terrible mistake that was, please
// increment the following counter as a
// warning to the next guy:
//
// total_hours_wasted_here = 16
//
// I'm sorry.
virgin = 0; /* you're not a virgin anymore, sweety */
... or die // bitch
// This is crap code but it's 3 a.m. and
// I need to get this working.
// Hard to explain

Tags: ,

Calculadora de notación polaca inversa en C

La Notación Polaca Inversa (RPN en inglés, Reverse Polish Notation) es un método de introducción de datos alternativo al algebráico. Fue creada en 1920 por el matemático polaco Jan Lukasiewicz como una forma de escribir expresiones matemáticas sin tener que utilizar paréntesis y corchetes.

En la notación polaca inversa los operadores suceden a sus operandos. Por ejemplo, la expresión algebráica5+((1+2)*4)-3se traduce a la notación polaca inversa como5 1 2 + 4 * + 3 -.

Su principio es el de evaluar los datos directamente cuando se introducen y manejarlos dentro de una estructura LIFO (Last In First Out), lo que optimiza los procesos a la hora de programar.

El siguiente programa es una implementación en C de una calculadora que funciona con notación polaca inversa. El programa es una versión modificada del que figura en el libro “El lenguaje de programación C” de Kernighan y Ritchie.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
## ************
## @file calc.c
## ************

#include <stdio .h>
#include <stdlib .h>

#define MAXVAL 100
#define NUMBER '0'

/**
 *  Variables
 */

int verbose;
int sp = 0;
double val[MAXVAL];

/**
 *  Prototypes
 */

int toi (char const *s);
void push (double);
double pop (void);

/**
 *  Main
 */

int main (int argc, char const *argv[])
{
  int offset, i;
  double op2;

  if (argc < 2)
  {
    fprintf (stderr,
      "Usage: %s [-v] EXP\n", argv[0]);
    return 1;
  }

  verbose = offset =
    (strcmp (argv[1], "-v") == 0) ? 1 : 0;
 
  for (i = 1 + offset; i < argc; i++)
  {
    switch (toi (argv[i]))
    {
      case '+' :
        if (verbose)
          printf ("operator +\n");
        push (pop() + pop());
        break;
      case '-' :
        if (verbose)
          printf ("operator -\n");
        op2 = pop();
        push (pop() - op2);
        break;
      case '*' :
        if (verbose)
          printf ("operator *\n");
        push (pop() * pop());
        break;
      case '/' :
        if (verbose)
          printf ("operator /\n");
        op2 = pop();
        if (op2 != 0.0)
          push (pop() / op2);
        else
          fprintf (stderr,
            "Error: division by zero\n");
        break;
      case NUMBER :
        push (atof (argv[i]));
        break;
      default :
        fprintf (stderr,
          "Error: unknown operator %s\n",
          argv[i]);
        break;
       
    }
  }

  // Result
  printf ("%f\n", val[0]);

  return 0;

}

/**
 *  Toi
 */

int toi (char const *s)
{
  return (isdigit(s[0])) ?
    NUMBER : (int) s[0];
}

/**
 *  Push
 */

void push (double e)
{
  if (sp < MAXVAL)
  {
    if (verbose)
      printf ("push %f in %d\n", e, sp);
    val[sp++] = e;
  }
  else
    fprintf (stderr, "Error: full stack\n");
}

/**
 *  Pop
 */

double pop (void)
{
  if (sp > 0)
  {
    --sp;
    if (verbose)
      printf ("pop %f from %d\n", val[sp], sp);
    return val[sp];
  }
  else
  {
    fprintf (stderr, "Error: empty stack\n");
    return 0.0;
  }
}
</stdlib></stdio>

Para compilarlo ejecutamos

$ gcc -o calc calc.c

A diferencia del programa original publicado en el libro de C, aquí se utiliza el arrayargv[]como fuente de operandos y operadores. Esto permite que podamos llamar al programa desde línea de comandos de la siguiente manera:

$ ./calc 5 1 2 + 4 \* + 3 -

Notar que para el caso especial del operador multiplicación, debemos escaparlo para evitar la expansión propia de bash antes de la llamada efectiva al programa.

El programa admite la opción-v(verbose), que muestra información acerca de uno de los pasos realizados.

Ejemplo I

$ ./calc -v 5 1 2 + 4 \* + 3 -
push 5.000000 in 0
push 1.000000 in 1
push 2.000000 in 2
operator +
pop 2.000000 from 2
pop 1.000000 from 1
push 3.000000 in 1
push 4.000000 in 2
operator *
pop 4.000000 from 2
pop 3.000000 from 1
push 12.000000 in 1
operator +
pop 12.000000 from 1
pop 5.000000 from 0
push 17.000000 in 0
push 3.000000 in 1
operator -
pop 3.000000 from 1
pop 17.000000 from 0
push 14.000000 in 0
14.000000


Read more »

Tags: ,

Accediendo a MySQL con Python y MySQLdb

MySQLdb es un módulo que implementa la API estándar (PEP249) para manejo de bases de datos, en este caso MySQL. MySQLdb es en realidad un wrapper del módulo _mysql que provee Python, el cual implementa la mayoría de las funciones definidas en la API C de MySQL. La idea de definir una API estándar es que uno debería poder cambiar a otra base de datos sin modificar demasiado el código.

This API has been defined to encourage similarity between the Python modules that are used to access databases.

Instalación MySQLdb

El paquete que nos provee el módulo se llama python-mysqldb. Podemos comprobar que lo tenemos instalado mediante

dpkg --get-selections | grep python-mysqldb

Si no existe lo instalamos

sudo apt-get install python-mysqldb

Para comprobar que efectivamente tenemos el módulo disponible y funcionando llamamos al intérprete de Python y escribimos

>>> import MySQLdb

Un silencioso retorno de carro indica que podemos el módulo ha sido cargado. Salimos del intérprete conC-d.

Creación de una DB de pruebas

Para nuestro ejemplo crearemos una base de datos con una única tabla. Entramos a la consola de MySQL y escribimos

mysql> CREATE database test;
Query OK, 1 row affected (0.01 sec)

mysql> USE test;
Database changed
mysql> CREATE TABLE users (
    -> id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> name VARCHAR(100),
    -> lastname VARCHAR(100)
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO users (name, lastname) VALUES
    -> ('Juan', 'Perez'),
    -> ('Ana Maria', 'Lopez'),
    -> ('Carlos L.', 'Gutierrez');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

Nuestra tabla users quedó entonces

mysql> SELECT * FROM users;
+----+-----------+-----------+
| id | name      | lastname  |
+----+-----------+-----------+
|  1 | Juan      | Perez     |
|  2 | Ana Maria | Lopez     |
|  3 | Carlos L. | Gutierrez |
+----+-----------+-----------+
3 rows in set (0.00 sec)

Creación del script mysqldb.py

Creamos el siguiente script que se conectará a la base de datos test y traerá todos los datos de los usuarios cargados en la tabla users. En el script es necesario reemplazar <user> y <pass> por los datos requeridos para acceder a tu DB.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/python
import MySQLdb

# Conexion a la base de datos
conn = MySQLdb.connect (host="localhost",
    user="<user>", passwd="<pass>", db="test")

# Creacion cursor
cursor = conn.cursor()

# Ejecucion query
cursor.execute("SELECT * FROM users")

# Manejo de datos devueltos por la consulta
while True:
    row = cursor.fetchone()
    if row is None:
        break
    else:
        print "id: %s\tname: %s %s" %
            (row[0], row[1], row[2])

# Finalizado cursor y objeto conexion
cursor.close()
conn.close()

La salida debería ser

id: 1   name: Juan Perez
id: 2   name: Ana Maria Lopez
id: 3   name: Carlos L. Gutierrez

Links recomendados para ampliar conocimientos

Tags: , ,

GNU gettext con php5

gnu-head-sm

GNU gettext es la biblioteca GNU de internacionalización (i18n) y es usada para escribir programas con interfaz en múltiples idiomas.

wikipedia

La internacionalización es el proceso de diseñar software de manera tal que pueda adaptarse a diferentes idiomas y regiones sin necesidad de cambios de ingeniería ni de código. La localización es el proceso de adaptar el software para una región específica mediante la adición de componentes específicos de un locale y la traducción de los textos, por lo que también se le puede denominar regionalización.

Es una práctica común en el idioma inglés (sobre todo en el ámbito de la computación), abreviar internationalization como “i18n”. Ello se debe a que entre la primera i y la última n de dicha palabra hay 18 letras. Lo mismo sucede con localization, que se abrevia “L10n”.

gettext en PHP

Existen dos formas de usar gettext en PHP: mediante la extensión gettext nativa de PHP o utilizando la librería PHP-gettext, escrita en PHP, que no necesita ninguna extensión.

La forma de usar gettext es

1
2
3
4
# @file: index.php
<?php
print _("hello world");
?>

La función_(), alias degettext(), devolverá la cadena “hello world” en el lenguaje correspondiente, de acuerdo al locale que hayamos seleccionado.

Si ejecutamos el script obtendremos “hello world” como salida, puesto que no hemos indicado ningún locale, ni creado ningún catálogo de traducción. Necesitamos crear el archivocomments.pocon la traducción de la cadena “hello world”. Esto puede hacerse mediante el comandoxgettext, o mediante un editor gráfico como poEdit.

apt-get install poedit

Creación del catálogo con poEdit

Ante todo debemos saber que la estructura de directorios para guardar los distintos catálogos tiene forma determinada. Por cada traducción se utiliza un directorio. Este generalmente se nombra usando dos letras minúsculas para el idioma, un guión bajo y dos mayúsculas para el país (es_AR, para español de Argentina). Dentro de este directorio debe existir otro con el nombre LC_MESSAGES, el cual será finalmente el directorio que contendrá el catálogo.

La estructura de nuestro ejemplo será

.
|-- locale
|   `-- es_AR
|       `-- LC_MESSAGES
|           |-- messages.mo
|           `-- messages.po
`-- index.php

El archivomessages.moes la versión compilada demessages.poy el que usará PHP para obtener la traducción.

Iniciemos poEdit. La primera vez nos preguntará por nuestro nombre y correo electrónico. Estos datos servirán para saber quién fue el último traductor que modificó el catálogo. Una vez en la ventana principal vamos a File -> New catalog. Seleccionamos el idioma (Español en este caso), el país y el código de caracteres tanto para el catálogo como para la fuente de datos desde la que obtendremos el listado de cadenas que requieren traducción. En la solapa Paths debemos colocar en ‘Base path’ la ruta completa al directorio base de archivos php (conteniendo las cadenas mencionadas anteriormente) y, debajo, en el cuadro ‘Paths’ agregar una entrada con ‘.’ indicando que se debe utilizar el directorio ingresado anteriormente. Al hacer click en OK aparecerá un cuadro de diálogo para guardar el nuevo catálogo. Navegamos hasta el directorio LC_MESSAGES y guardamos el archivo como messages.po. poEdit escaneará el directorio ingresado en Paths y extraerá todos las cadenas gettext. Ahora queda simplemente realizar la traducción y guardar el archivo. Al guardarlo, poEdit lo compilará y generará el .mo que finalmente usará PHP.

Ahora, modificaremos index.php para setear el locale

1
2
3
4
5
6
7
8
9
10
11
12
13
# @file: index.php
<?php
$language = 'es_AR.UTF-8';
putenv("LANG=$language");
setlocale(LC_ALL, "");

$domain = "messages";
bindtextdomain($domain, "./locale");
bind_textdomain_codeset($domain, 'UTF-8');
textdomain($domain);

print _("hello world");
?>

Aun nos queda un paso y es comprobar que tengamos dicho locale habilitado en nuestro sistema. Esto lo hacemos mirando la salida de

locale -a

Si no tenemos habilitado el charset es_AR.UTF8, ejecutamos

locale-gen es_AR.UTF-8

En este punto la salida del script debería ser la traducción que hicimos al español.

Tip

Para casos en que la cadena a traducir contenga variables, podemos utilizar esta función:

1
2
3
4
5
6
7
8
9
10
function __($string)
{
    $arg = array();
    for($i = 1 ; $i < func_num_args(); $i++)
        $arg[] = func_get_arg($i);
    return vsprintf(gettext($string), $arg);
}

$total = 400;
print __("results %d - %d of about %d", 1, 20, $total);

La traducción podría quedar

resultados %d - %d de aproximadamente %d

Tags: , , ,

Code Golf – Saving Time

Code Golf es un sitio donde se juega a resolver problemas informáticos en la menor cantidad posible de pulsaciones de tecla. Para ello pueden utilizarse lenguajes como Perl, PHP, Python y Ruby. Quien resuelva el desafío en menor cantidad de keystrokes es quien tendrá mayor puntaje.

Me anoté en uno llamado Saving Time y llegué al puesto 20 de PHP, con 245 keystrokes. (2009-03-27: Aunque ahora me encuentro en el 22, malditos nerds!)

El desafío consiste en crear la cara de un reloj analógico partiendo de una hora dada en formatohh:mm. Algunas de las reglas son

  • La hora dada en hh:mm se representa con una ‘h’ minúscula.
  • La hora que indica los minutos dados en hh:mm se representa con una ‘m’ minúscula.
  • Cuando hora y minutos coinciden en la misma posición se representa con una ‘x’ minúscula.
  • El resto de las horas se representan con una ‘o’ minúscula.
  • Los minutos deben redondearse al múltiplo de 5 más cercano (23 se convierte en 20, 39 en 35, etc.)

Salida del programa

Código

<?$f="874D1F0D1748110202020201";
list($h,$m)=split(':',fgets(STDIN));
if($h>=12)$h-=12;
$m=floor($m/5);$a=$i=12;
while($i){$a+=$i%2?$i:-$i;
echo str_pad("",hexdec($f{--$i})).
(($a==$h)?($h==$m?'x':'h'):($a==$m?'m':'o')).
str_repeat("\n",$f{$i+12});}?>

El string hexadecimal $f contiene el formato necesario para “dibujar” el reloj. Para interpretarlo es necesario dividirlo en dos mitades. La primera mitad contiene, en cada caracter hexadecimal, la distancia a la que se encuentra respecto de su elemento anterior, que puede ser el número de la izquierda o un salto de línea. De aquí surge el por qué de haber usado el sistema hexadecimal: el espacio mayor a representar es 15. En la segunda mitad cada caracter representa la cantidad de saltos de línea que preceden al caracter.

Tags: ,

Pattern Singleton en PHP4

A pesar de sus limitaciones en cuanto a orientación a objetos, PHP4 permite implementar un pattern del tipo Singleton.

Por defecto, en PHP4 (y a diferencia de PHP5) los objetos se devuelven/asignan por valor (una copia), por ello es necesario indicar expresamente que deseamos devolver/asignar una referencia del objeto en cuestión.

Una de las formas más elegantes de implemetar este pattern es:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Clase de la cual deseamos que exista
// una única instancia en todo el programa
class Config
{
   var $message = null;

   function set($message)
   {
      $this->message = $message;
   }

   function get()
   {
      return $this->message;
   }
}

// Pattern que se ocupará de devolver
// la única instancia de la clase Config
class Singleton
{
   // Método que devuelve una referencia al objeto
   function &get()
   {      
      static $instance;
     
      if ( ! isset($instance) )
      {
         $instance = new Config();
         print "instancia creada.\n";
      }
     
      return $instance;      
   }
}

// Forma de uso
$config =& Singleton::get();
$config->set('hello world.');
printf("%s\n", $config->get());

$config =& Singleton::get();
printf("%s\n", $config->get());

Salida del programa

instancia creada.
hello world.
hello world.

Tags: , ,

Javascript no intrusivo

Forma de usar Javascript fuera del flujo HTML:

1
2
3
4
5
6
7
8
9
10
11
12
<head>
  <script type="text/javascript">
    window.onload = function() {
      var reloj = document.getElementById("reloj");
      var fecha = (new Date()).toLocaleString();
      reloj.innerHTML = fecha;
    }
  </script>
</head>
<body>
  <div id="reloj">No te puedo mostrar la hora</div>
</body>

Tags: , ,

Webserver en Java

Se trata de un sencillo servidor web que hice recientemente, en Java. Sus características son:

  • Maneja Theads, lo que le permite atender peticiones simultáneas
  • Sirve los siguientes tipos de archivos: html, xml, css, js, txt, ico, png, gif, jpg y pdf
  • Implementa los dos errores más comunes: 404 y 403
  • Lleva un registro de logs al estilo combined de Apache
  • Tiene una salida por consola de cada petición hecha, con los mensajes enviados durante el Request

Código fuente: webserver-java.tar.gz

Tags: ,

Generando Captchas con PHP

Captcha es el acrónimo de Completely Automated Public Turing test to tell Computers and Humans Apart (Prueba de Turing pública y automática para diferenciar a máquinas y humanos).

Se trata de una prueba desafío-respuesta utilizada en computación para determinar cuándo el usuario es o no humano. Como el test es controlado por una máquina en lugar de un humano como en la prueba de turing, también se denomina Prueba de Turing inversa.

Clase Captcha

Esta es una clase que hice para www.lamarchaperonista.com.ar que genera captchas usando fuentes True Type (.ttf). La clase tiene varios métodos para personalizar el captcha, generar el código y seteralo en una variable de sesión de PHP.

La forma de usarla es realmente simple. Sólo hay que crear un script que contenga la clase y devuelva el captcha. Este mismo script será el encargado de generar el código y guardarlo en una variable de sesión:

// File: getCaptcha.php
requiere_once('Capcha.php');
session_start();

// Creo un captcha de 150 x 50 px
$captcha = new Captcha(150, 50);

// Creo y seteo en $_SESSION el código de 4 caracteres
$captcha->setSessionVar(4);

// Seteo la fuente TTF a usar
if ($captcha->setFontFile('ArsleGothic.ttf')) {

   // Seteo el tamaño de la tipografía
   $captcha->setFontSize(24);

   // El color
   $captcha->setFontColorWeb('716052');

   // Envío la imagen
   $captcha->sendCaptcha();

}

Al ser llamado desde otra página (como esta), mediante

&lt;img scr="getCapcha.php"/&gt;

, el script generará un captcha como el siguiente:

Captcha generado con la clase Captcha.php
generar nuevo

Luego, en el script que controla los datos que vienen del formulario (en el que el captcha fue mostrado), hacemos algo como esto:

// File: checkForm.php
requiere_once('Capcha.php');
session_start();

// Creo una instancia de Captcha, pero sin pasarle parámetros,
// ya que no voy a generar ninguna imagen.
$captcha = new Captcha();

// Traigo el código del captcha (seteado en $_SESSION)
// y lo comparo con el que me vino del formulario
if ( $_POST['codeCaptcha'] == $captcha->getCode() ) {

   // lo que haré en caso de coincidir los códigos.

}
else {

   // lo que haré en caso de NO coincidir los códigos.

}

Otro ejemplo

La clase tiene varios métodos más para setear las distintas propiedades del captcha, como el color de fondo, la densidad del ruido (las lineas que aparecen detras del texto) y el color del mismo.

Captcha generado con la clase Captcha.php
generar nuevo

$captcha = new Captcha(280, 70);
$captcha->setSessionVar(6);
if ($captcha->setFontFile('BagadBold.ttf')) {
   $captcha->setFontSize(32);
   $captcha->setFontColorWeb('00497B');
   $captcha->setBgColorWeb('5C9FCC');
   $captcha->setNoiseColorWeb('0069B0');
   $captcha->setNoiseFactor(70);
   $captcha->sendCaptcha();
}

Existen métodos para setear los colores pasando el código hexadecimal, ej.

setFontColorWeb("FF0033")

, y para setearlos pasando los valores por cada canal, ej.

setFontColor(255,0,51)

.

Archivos y documentación

El código junto con la documentación pueden bajarse desde aquí: Captcha.tar.gz
La documentación también puede verse en línea en http://blog.calcifer.com.ar/devel/captcha/doc
Un buen sitio para bajar fuentes TrueType es http://www.creamundo.com/

Tags: ,

Función para generar passwords aleatorios

Vía Intenta

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function generarClave($longitud)
{
   $caracteres=array();
   $clave='';

   # números
   for($i=48; $i&lt;=57; $i++)
      array_push($caracteres, chr($i));

   # mayúsculas
   for($i=65; $i&lt;=90; $i++)
      array_push($caracteres, chr($i));

   # minúsculas
   for($i=97; $i&lt;=122; $i++)
      array_push($caracteres, chr($i));

   for($i=0; $i&lt;$longitud; $i++)
   {
      mt_srand((double)microtime()*1000000);
      $clave .= $caracteres[mt_rand(0,count($caracteres))];
   }

   return $clave;
}

Otra opción es usar el identificador de sesión (session id) para obtener la contraseña de él:

session_start();
$password = substr (session_id(), 0, 10);

Tags: , ,