Menéame dispone de dos sistemas de captcha: el proporcionado por recaptcha y el normal. Al instalar meneame a partir del código fuente disponible, se autoconfigura para usar el normal. Y así lo hacen en sitios como enchilame y similares. Lamentablemente, el sistema de captcha normal es muy vulnerable, y con un simple código en C de menos de 120 líneas, se puede superar.
#6:
No es importante que sea el de menéame o cualquier otro. Es interesante ver la forma de resolver el problema que adoptó el autor.
Para aquel que no entienda, la idea es "escanear" todos los puntos de una misma línea (la 20). El color se expresa en RGB, sistema en el cual el rojo, el verde y el azul pueden tomar valores de 0 a 255, para formar muchísimas combinaciones. El color blanco es la suma de todos los colores, entendiéndose por eso rojo = 255, verde = 255, azul = 255. De esta forma, y teniendo en cuenta que en el fondo (naranja) las tonalidades azules son bastante pequeñas, deduce que cualquier pixel con valor azul > 100 es "blanco", o sea, parte de un dígito.
Desde ahí es fácil ver que cada número está formado por combinaciones de píxeles diferentes, y que incluso una línea alcanza para distinguir un 3 de un 4, por ejemplo.
En una ocasión estaba en un tren hablando con un colega sobre una demo que había visto en la que se utilizaba una rutina para rellenar vectores. La rutina era tan rápida que rellenaba los vectores en tiempo real mientras la figura giraba y temblaba como si fuera de gelatina. Los llamábamos Glenz Vectors. Un señor que iba en el tren nos preguntó que de donde éramos.
-De málaga.
-No... pero.. digo ¿donde nacisteis?
-... En Málaga.
-¿Y donde os habéis criado?
-...Aquí en Málaga.
-Es que... no puede ser. Habláis muy raro. Yo soy de Málaga y nunca he oído a nadie hablar así. Usáis unas palabras mu raras. En serio, ¿de donde sois?
_______________________________________
Esta conversación tuvo lugar hace 20 años.
¿Acabar pasando? Ya pasó, ha pasado siempre. Igual que si se ponen a hablar dos médicos o dos Albañiles. Fuera de su gremio poca gente los entenderá.
#14:
#11 ¿Quejarse sobre los votos de los demás se ha convertido en el comentario cansino por excelencia? ¿Se convirtió ya hace tiempo?
#19:
"El caso es que estoy ayudando a mi novia a entender C/C++, sistemas y todo eso, así que decidí que hoy programaría algo con ella (algo simple,para empezar)"
Como informático que soy, horrorizado me hallo. ¿No tienes mejores cosas que hacer con ella que enseñarle a programar?
No es importante que sea el de menéame o cualquier otro. Es interesante ver la forma de resolver el problema que adoptó el autor.
Para aquel que no entienda, la idea es "escanear" todos los puntos de una misma línea (la 20). El color se expresa en RGB, sistema en el cual el rojo, el verde y el azul pueden tomar valores de 0 a 255, para formar muchísimas combinaciones. El color blanco es la suma de todos los colores, entendiéndose por eso rojo = 255, verde = 255, azul = 255. De esta forma, y teniendo en cuenta que en el fondo (naranja) las tonalidades azules son bastante pequeñas, deduce que cualquier pixel con valor azul > 100 es "blanco", o sea, parte de un dígito.
Desde ahí es fácil ver que cada número está formado por combinaciones de píxeles diferentes, y que incluso una línea alcanza para distinguir un 3 de un 4, por ejemplo.
En una ocasión estaba en un tren hablando con un colega sobre una demo que había visto en la que se utilizaba una rutina para rellenar vectores. La rutina era tan rápida que rellenaba los vectores en tiempo real mientras la figura giraba y temblaba como si fuera de gelatina. Los llamábamos Glenz Vectors. Un señor que iba en el tren nos preguntó que de donde éramos.
-De málaga.
-No... pero.. digo ¿donde nacisteis?
-... En Málaga.
-¿Y donde os habéis criado?
-...Aquí en Málaga.
-Es que... no puede ser. Habláis muy raro. Yo soy de Málaga y nunca he oído a nadie hablar así. Usáis unas palabras mu raras. En serio, ¿de donde sois?
_______________________________________
Esta conversación tuvo lugar hace 20 años.
¿Acabar pasando? Ya pasó, ha pasado siempre. Igual que si se ponen a hablar dos médicos o dos Albañiles. Fuera de su gremio poca gente los entenderá.
"El caso es que estoy ayudando a mi novia a entender C/C++, sistemas y todo eso, así que decidí que hoy programaría algo con ella (algo simple,para empezar)"
Como informático que soy, horrorizado me hallo. ¿No tienes mejores cosas que hacer con ella que enseñarle a programar?
#4 ¿Acabar pasando? Si ha sido toda la vida sí. Yo hay veces que me pongo a hablar con mis compañeros en la Universidad y me doy cuenta de que una de cada cinco palabras son siglas raras. Ejemplo práctico:
"El otro día estuve aprendiendo XSLT para generar XHTML. Las DTD dieron problemas, pero bueno. Con CSS puedes definir el estilo y hasta el layout, con DIVs. También miré XPath, para acceder al DOM desde JavaScript. Si es que, aunque me guste más YAML, el XML no está mal del todo..."
esta noticia es "divulgativa total"...tengo una pregunta: ¿a los informáticos y 'weberos' les acabará pasando como a los críticos de arte, que no hay quien les entienda?
#48: Pero es que la aritmética binaria ya sería un nivel superior. Primero tienes que aprender cosas sencillitas: IF, SWITCH, sumar, restar, funciones, valores float e int... Luego cuando controlas eso ya pasas a punteros, aritmética binaria, y demás historias.
Por supuesto que lo que pones es sencillo, pero para aprender un lenguaje, no ayuda nada, porque te obliga a pensar en muchas coass al mismo tiempo en lugar de concentrarte en lo que realmente quieres aprender.
#28: Que quieres que te diga, pero para principiantes está genaial. Yo he visto algún código fuente de programas más o menos serios, y no me entero de mucho, están llenos de constantes, enumeraciones, funciones para todo... En cambio, ese programa, si lo he entendido bien, no tengo que estar de un lado para otro.
Primero cargas la imágen JPEG, luego te vas a la linea del medio y punto por punto vas cargando un vector de 7 elementos. Y cada vez que metes 7 elementos en el vector, comparas el vector con diferentes patrones con la función de más arriba. La función también se encarga de escribir en pantalla.
Además, el código espagueti es cuando se abusa de GOTO, no cuando metes "números mágicos" y demás.
Quizás se eche de menos algún comentario explicando los "números mágicos" en la linea donde están (no al principio), y las funciones, pero yo creo que es un programa bastante claro.
#30: Eso que propones de mejorar la memoria, es contraproducente. Si, ganas memoria (¡7 bytes!) pero a cambio tienes que meter algo de complejidad al programa, aumentas el riesgo de meter errores (bugs), y sobretodo, lo que ganas en memoria lo pierdes en tiempo de proceso, al incluir sentencias extra. Tampoco es que sea mala idea lo que propones (es más, se agradece que la gente haga aportaciones), pero yo creo que no merece la pena.
#25 Pero si no tienes ni idea de lo que estamos hablando, te dará igual que lo llamemos de una forma u otra, que usemos una jerga u otra. Si no sabes lo que es CSS, poco te importará que lo llamememos CSS o hojas de estilo en cascada.
La cuestión no es la jerga, la cuestión es que quizás no expliquemos en detalle cada concepto. Por ejemplo, al hablar de CSS podría poner entre paréntesis que es un documento de texto vinculado a una página web que fija el estilo de la misma.
Pero la verdad es que carecería de sentido explicar cada concepto que una persona sin conocimientos de informática desconociese, ya que el público al que escribes es informático y conoce esos términos.
Y menéame es un site de promoción de noticias GENERAL específicas. Es decir, tienen cabida en él todo tipo de temáticas, con noticias más o menos específicas. Y el hecho de que se incluyan noticias generalistas, no significa que no se puedan incluir noticias de temática técnica, ya que mucha gente de la comunidad disfruta viéndolas, como es mi caso.
Veo codigo espagueti y que no se respeta el principio DRY -y estas son dos cosas que me duele ver-
No veo apenas comentarios ni nombres lo suficientemente descriptivos. ('checkNumber' es una funcion que, como su propio nombre indica, dibuja un numero por pantalla dependiendo de la posicion en la que este un 1 -si es unico- en un array... )
Veo 'numeros magicos' que no se de donde salen z=22? z
No me referia a ti, me referia al codigo que hay actualmente en la pagina (esos ifelses anidados de 8 clausulas horribles). El switch que pones me parece lamentablemente inevitable (snif) y tu solucion me parece inmejorable, bueno, solo mejorable con tabulaciones. (ya se que se habran prerdido por el camino, es que es la unica cosa que seria capaz de criticar).
Sobre lo del entero evidentemente me parece mejor en todos los sentidos menos en el didactico.
Me parece que es mas visible por una persona que no sabe ver los unos y ceros como numeros decimales que como una secuencia de bits. Solo digo que realmente en el fondo tu solucion (secuencia de unos y ceros) y la de la pagina (array de numeros que solo pueden ser uno o cero) son el mismo en concepto pasa que el autor piensa que es mas facil explicarle el concepto a un lego dispuesta la informacion de ese modo.
Pero solo es una opinion personal.
Nunca criticaria tu codigo (ni pisaria la cuerda de un/a escalador/a)
Yo desde el primer momento asumo que es un ejemplo para alguien que no sabe programar, e incluso entiendo el mecanismo para llegar a escribir eso. Me parece una buena manera de explicarlo a un lego en la materia como tu novia contigo al lado.
Pero no es muy buen codigo... y no me parece un ejemplo para aprender a programar para alguien que no sea tu novia a la que tienes al lado como decia #10 que es lo que he comentado en un ppio. Quiero decir: si tuviera que hacer un tutorial para que la gente aprendiera a programar no lo usaria...
Mierda no se si se me entiende... a estas horas solo tengo ganas de beber... me desdigo y me piro.... continuarmos con el flame del spaguetti western
PD: Mola eso de enseñar a programar a la novia, lo voy a hacer yo con la mia, pero no usare C: DEGENERAO!
#36 Perdona, había malinterpretado tu comentario. De todas formas, gracias por lo de inmejorable Lástima que se pierda la indentación cuando envías un mensaje. Se me ocurren maneras de hacerlo más eficiente, como usar una lookup table para guardar las representaciones binarias y hacer que checkNum sea O(1), pero eso ya es pasarse.
#28 Yo entiendo que ha sido un programita hecho a prisa y corriendo. Sin embargo hay algunas cosas que me preocupan y que ya no tienen que ver con la prisa, sobre todo el uso de un array de enteros para guardar valores 0/1 (bits al fin y al cabo) en lugar de usar un único char y aplicar aritmética binaria.
Le he dejado un comentario en el blog explicando cómo mejorar la eficiencia, reducir el uso de memoria y aumentar la legibilidad del código, supongo que no tardará en aprobarlo.
#31 Creo que es curioso que critiques la solución que le he enviado... si todavía no ha aprobado el mensaje
Precisamente el ahorro que propongo hace que vaya más rápido y reduzca la complejidad y, de rebote, haga el código más legible. Dime qué bug y complejidad añado si, en lugar de tener un array de 8 enteros (donde cada uno ocupa 4 bytes en un procesador i386, es decir 32 bytes), hago esto:
unsigned char positivos = 0;
...
// bucle que escanea las líneas
...
// Vamos añadiendo "por la cola" los resultados de comprobar si color
// mayor que 100 o no (1 si lo es, 0 si no).
positivos = positivos 100);
Memoria ocupada: 1 byte. Además, en la función checkNum sólo es necesario un bloque switch...case que compruebe "positivos". Habiendo definido las constantes como los valores decimales de la representación binaria, el código queda así:
void checkNumber(unsigned char positivos, int check) else
break;
case TWO:
printf(”2″);
break;
...
// continúa
}
Resultado final: menor complejidad, más eficiencia, menor consumo de memoria y, además, más legibilidad (porque no me negarás que tener que leer un if con 8 cláusulas no es lo más legible del mundo).
Mola, jcarlosn, creo que tienes un fan, Ap0 espero que no se vuelva como http://en.wikipedia.org/wiki/Mark_David_Chapman Curioso que haya votado en contra de mi último comentario, no creo que haya insultado a nadie y he argumentado (todo lo bien que he podido) mi opinión.
#45 Han habido muchos códigos antes que este, hombre, mas básicos al principio, etc, este no ha estado mal.
La curva de aprendizaje de C es bastante fuerte (yo no he elegido enseñarle C, ella ya sabia un poco, muy poco, de la uni), primero hay que pelearse con el manejo de la memoria, stack, heap (memoría dinámica), etc y luego, pelearse con interpretaciones de esa memoria (casts) y luego con apuntadores a esa memoria (punteros) y es todo un gran lío, si mientras intentas que alguien comprenda BIEN y a fondo el manejo de memoria, empiezas a comerle la olla con que un bloque de ifs puede ser sustituido con 8 bits y operaciones a nivel de bits, esto es contraproducente.
Yo creo que es bastante fácil de entender el problema:
Si yo te enseño X, mientras te enseño X surge Y y salto a Y, y entonces surge Z y salto a Z, la persona no aprende NADA, y desde luego, espero que no os tengáis que ver en la tesitura de enseñar C a alguien, por que no es una tarea sencilla, es mil veces mas fácil enseñar java o python, si es que puedes elegir, claro.
Pero bueno, que cada uno ve la forma de enseñar a su manera, y evidentemente, el como enseñar, también radica mucho en quien es la otra persona y como es, que capacidades tiene, que base tiene, y cual son sus puntos fuertes y flojos, por eso no tiene sentido aquí juzgar como enseño a mi novia a programar, no llegariamos a ningún lado con esta conversación.
El código y la explicación queda ahí, nadie ha dicho que sea un super código, es un PoC del estilo de #46.
Lo de spagetti code tambien se aplica a if-elses anidados en if-elses anidados en.... switches etcetera... Son elementos de control que hacen el codigo farragoso y dificil de seguir. Al menos yo siempre lo he usado en ese sentido...
Y otra cosa muy mala del codigo:
Para enseñar a programar a tu novia usa python o asi... pero C... degenerado! luego nos dejan y nos quejamos!!!
Bueno, me han gustado mucho los comentarios, mola ver que no siempre nos encontramos los mismos en los mismos flames, sino que a veces son charlas constructivas. (a alguien le puse un negativo sin querer, quería ser un positivo, lo siento!).
Sin embargo hay una cosa en la que discrepo enormemente con vosotros... y es el tema del spagueti code, simplemente, yo no veo el código espagueti en ningún sitio, es así de simple.
Este tipo de código se conoce como PoC (proof of concept, o en castellano, prueba de concepto), los PoC se caracterizan por ser pruebas rápidas a problemas de seguridad.
Voy a poner un ejemplo, se encuentra un bug en el servicio X, normalmente alguien crea un programa que lo explota (exploit), ese programa no se hace siguiendo un procedimiento de rational, creando uml's etc etc, luego creando 'use cases', programandolo, depurandolo y perfeccionandolo, nada mas lejos.
Por que no? por que sería ridículo, es una PRUEBA DEL CONCEPTO, no un programa en producción.
Pero como esto no ha derivado en un flame sin sentido, voy a explicar un par de cosas, por que ya que os habéis puesto en plan crítico, en un código que he intentando simplificar para mi novia, vamos a profundizar en el tema:
1. El problema de los ifs tal como se ha dicho arriba se puede solucionar con aritmetica binaria, y aquí a todo el mundo se llena la boca con ello, bien, vale, creeis REALMENTE que esto es legiable para alguien que está aprendiendo?:
positivos = positivos 100);
Super legible, si señor.
Eso es completamente ILEGIBLE para alguien con poca experiencia en la materia, no por que no sepa aritmetica binaria, sino por que si a alguien que anda al limite haciendo un programita de prueba, le agregas eso, lo matas, su cerebro explota ya, por eso, hay que ir por partes.
Sin embargo, como a todo el mundo se le llena la boca con esta solución voy a comentar un par de cosas a #32:
un array de 8 enteros (donde cada uno ocupa 4 bytes en un procesador i386, es decir 32 bytes),
Un entero ocupa 32bits, no 32bytes, pero me imagino que esto ha sido un tipo
Aparte de esto, afirma que tu unsigned char mide 1bytes, como lo sabes? No es siempre así en todas las arquitecturas, por eso al hacer malloc para almacenar 32 chars no se hace:
A datatype or synonym for a datatype in certain programming languages. C and C++, for example, defines byte as "addressable unit of data storage large enough to hold any member of the basic character set of the execution environment" (clause 3.6 of the C standard). Since the C char integral data type must contain at least 8 bits (clause 5.2.4.2.1), a byte in C is at least capable of holding 256 different values (signed or unsigned char does not matter). Various implementations of C and C++ define a "byte" as 8, 9, 16, 32, or 36 bits[4][5]. The actual number of bits in a particular implementation is documented as _CHAR_BIT_ as implemented in the limits.h file.
Va bien esto para no olvidar nunca que char != byte en C, siempre hay que mirar el sizeof o bien la constante de limits
Pero bueno, habiendo explicado el por que del bloque de los ifs, que creo que cualquiera que enseñe a otra persona a programar, entenderá por que no he agregado las operaciones a nivel de bits.
Yo creo que todas estas explicaciones, sobre si char es un byte realmente o no lo es, sobre si operaciones a nivel de bits hubiesen sido mejores o no...no son el momento para la persona a quien intento ayudar a en sus estudios (estudia informática)
Este código fue hecho para enseñar, para probar la libjpg y poco mas, nadie debe entenderlo como código en producción.
Lo que no entiendo es el motivo de ponerse a analizar un PoC como si de un código stable y en producción se tratase, al final no se ha creado flame, y es bonito, pero por que al final tenemos que andar midiendonosla siempre de meneo en meneo, a ver quien la tiene mas grande? Es ridículo.
Si queréis, como ejercicio divertido, un día creamos cada uno un pequeño código stable para algo, y nos la medimos bien, hombre
P.D. al ser un PoC y encima para ayudar a alguien a dar sus primeros pasitos, el código tiene MUCHISIMOS fallos mas, y además mucho mas graves
#30 los comentarios en rooibo se aprueban solos, no se que habrá pasado, voy a mirar en akismet
#40: Si no te digo que no sea una solución mejor, pero a mi, lo primero que se me habría venido a la cabeza es esa solución, puesto que me parece más fácil de programar y de pensar al principio. Luego, con esa solución delante de mis ojos funcionando, podría ocurrirseme la tuya, pero lo primero que se me vendría a la cabeza es lo del autor.
Piensa que lo que haces es "si esto es como lo otro, tal, y sino...tal tal tal..." es decir, primero piensas en IFs. A mi no me parece tan mala la solución que propuso el autor, una cosa es que sea mejorable, y otra que lo tachen de código espagueti y malo a la primera.
#30 a mi me parece mas de 'deprisa y corriendo' la aritmetica binaria que el tema DRY y spageti.
Creo que una cosa me duele a los ojos y convierte el codigo en ilegible y lo otro es una licencia para que su interlocutora lo entienda mejor, que, aunque sea una burrada en temas de rendimiento, veo a menudo -de hecho yo eso lo empece a utilizar cuando trabajaba en moviles que necesitabamos cada bit. En J2EE, que es lo que mas se hace, seguramente no influya mucho... se compra otro servidor y ya esta! (lo he visto hacer)-...
Diferencia de apreciaciones. Pero en fin.... mola.
#56 ¿Es una prueba de concepto de cómo se usa la libjpeg o un ejercicio para enseñarle a tu novia a programar? Si es lo segundo puedes aprovechar para, en la siguiente iteración del programa, enseñarle a calcular límites asintóticos y a utilizar estructuras de datos. Es mejor que lo vea en un algoritmo sencillo como ese que no en uno mucho más complejo.
Supongo que será un error, pero no se trata de crear una lookup table y una tabla de hash, sino que lookup table es un concepto y la tabla de hash la estructura para implementar esa idea. Una lookup table puede ser también un array, una lista o un árbol.
Por cierto, puedes aprovechar ahora y enseñarle a liberar la memoria reservada por el malloc y a cerrar los descriptores de ficheros
#54: Claro que si, pero primero hay que saber como funciona un ¡Hola mundo!
Luego, empiezas a ver la aritmética normal, las funciones de entrada y salida scanf y printf.... algo así: printf("bla %i n", 4*5+3);
Luego metes las variables y ya empiezas a hablar de como van los tamaños...
Luego metes los IF, SWITCH...
Y sigues metiendo.
Sobre si C es difícil para principiantes, a mi no me lo parece si se enseña bien, por orden y sin meter muchos conceptos nuevos a la vez.
Yo sigo en mis trece, y viendo esta noticia en portada no tengo mas remedio que hacerme unas preguntas que lanzo solo como reflexión sobre el funcionamiento de meneáme.
¿De verdad el como romper un captcha que ya no se usa, es lo suficientemente interesante para llegar a portada?
¿Cuantos de los que han votado saben lo suficiente de programación, para saber si lo que se dice es correcto?
Resumiendo:
¿hablar de meneáme, se ha convertido en una garantía de portada?
#48 lo siento, pero la aritmetica binaria la aprendí hace muchos años
Bromas aparte, claro que no me lo tomo a mal, pero es que no es mi código
Los pasos han sido así:
1. propongo algo ameno que programar a alguien que aprende, romper el captcha este, que es bastante sencillo
2. lo programamos, vamos haciendo partes y hablando las cosas
3. queda un PoC bastante cutre, lo repasamos un poco
4. queda un PoC normalillo, lo publicamos como divulgación
Pero no me ha molestado tu comentario, seguramente, yo hubiese hecho lo mismo, es algo normal, por eso he querido aclarar que se trata de un PoC realizado como ejercicio de practicar un poco el C, pero liberado como ejemplo, por si a alguien le sirve, como mínimo para ver la jugada con libjpeg.
Vaya, que no hay mal rollo, es mas, ojala mi novia lea tu comentario, y aproveche para preguntarme, y un día de estos le explico un poco mas, y hacemos una versión mejorada y mas decente
#11 no se usa en meneame, pero si en los clones... lo que permitiría atacarlos con spam. Eso afectaría a ciertos clones muy interesantes, en el caso que no usaran el mismo sistema que usa ahora Meneame.
#27 Si hawkings consiguió publicar un libro de divulgación científica sobre la creación del universo medianamente entendible, impossible is nothing. Como ya dije, lo primero son las ganas.
PD. Soy estudiante de ingeniería informática. No hablo por mí.
Si sustituyeras "x*3*cinfo.output_width" por una variable temporal, y la asignaras su valor antes de entrar al bucle iría un poco más rápido. Es un detalle sin importancia que digo como curiosidad, porque es un programa muy interesante para aprender.
#52 y #53 Yo creo sin embargo que, puesto que lo que se va a programar es un ordenador, hay que saber al menos un poco de la teoría de cómo representa la información por dentro. De todas formas, en el código hay un puntero y un malloc, cosas que creo que son más difíciles de entender que sumar, restar o desplazar números (binarios, en este caso).
También creo que no se le da tanta importancia a temas más "teóricos" como la algoritmia (cálculo del orden, estructuración, etc.), por ejemplo, si usas una lookup table y una tabla de hash puedes hacer que sea O(1) o que al hacer lo "raro" de los números, el número de comprobaciones se reduce a 10 (o menos).
#39 Pues si alguien se pone a programar sin saber utilizar lo mínimo del sistema binario, su representación y las operaciones que puede hacer, mal vamos. Por ejemplo, en un post de la programadora principal de Pownce:
demuestra que no sabe lo más mínimo de aritmética (no ya binaria) ni de algoritmia. Parece poco importante, puesto que los procesadores actuales son muy rápidos, pero el código original es excesivamente complejo.
La mayor ventaja que le veo a mi solución es que hace el código más legible, puesto que puedes comparar directamente la constante ZERO (11000011 en binario, 195 en decimal) con el valor de la variable "positivos", mientras que en la solución original hay que comparar cada una de las posiciones del array.
Lo peor de todo es que no estoy hablando de una representación compleja, sino de algo fundamental (el sistema binario) que debería estar grabado a fuego en la cabeza de todos los programadores.
Si es sencillísimo, se ve muy claro: si no es esto, vamos a probar esto otro, si tampoco lo es, probamos esto otro, si tampoco lo es...
Vamos, yo lo veo más claro que si se hubiera hecho una función que evitara repetir el código.
#32: Si, tienes razón, es más eficiente, aunque es más complejo de ver, y te juegas más meter un error si eres principiante. El ahorro de memoria es insignificante hoy en día, pero no está mal saber ese detalle para proyectos más grandes donde si se note el ahorro.
#33 y #34 Pues sinceramente, creo que es un error grave pensar que para representar un conjunto de bits haya que usar un array de enteros. No ya por eficiencia (total, con los procesadores que tenemos y la cantidad de memoria, para un programita así de pequeño no merece la pena sacarle hasta la última gota), sino por legibilidad. Cualquier buen programador debe tener por la mano todas estas cosas de representaciones binarias, algoritmia, etc.
De todas maneras, si consideras que un if dentro de un switch...case (como el de mi solución) es código spaghetti, ya me dirás cómo solucionarías el mismo problema (que un mismo valor pueda representar dos soluciones distintas y que necesite una segunda comprobación).
#43 1. El problema de los ifs tal como se ha dicho arriba se puede solucionar con aritmetica binaria, y aquí a todo el mundo se llena la boca con ello, bien, vale, creeis REALMENTE que esto es legiable para alguien que está aprendiendo?:
positivos = positivos 100);
Super legible, si señor.
Sé que puede parecer intransigente, pero si esa persona no entiende una cosa tan sencilla, entonces no está preparada para programar aún. Luego nos quejamos de que se enseñan demasiadas mates. De todas formas, puedes usarlo para enseñarle aritmética binaria, ¿no crees? Por otra parte, he puesto un comentario para aclarar lo que hacía, aunque tal vez no sea el más claro del mundo
un array de 8 enteros (donde cada uno ocupa 4 bytes en un procesador i386, es decir 32 bytes),
en.wikipedia.org/wiki/Integer(computer_science)_
Un entero ocupa 32bits, no 32bytes, pero me imagino que esto ha sido un tipo :-P
Nope, no ha sido una equivocación, 4 bytes * 8 enteros = 32 bytes, pensaba que era suficientemente claro. De todas formas el enlace a lo que es un byte... bueno, ha sido didáctico
Va bien esto para no olvidar nunca que char != byte en C, siempre hay que mirar el sizeof o bien la constante de limits :-)
char The most basic unit addressable by the machine; typically a single octet. This is an integral type.
No sabía que (no te lo tomes a mal, anda ;-))
[ironic mode on]
a) hubieras pensado el programa para arquitecturas de 16 bits
b) hayas estado ejecutando el programa en un Linux en 16 bits (ya sé, ya sé, ELKS)
[ironic mode off]
es decir, que el char es el tipo de dato más pequeño para la arquitectura en la que programabas y además, es suficiente para almacenar TODA la información que necesitas.
Mi opinión es que es línea tan "rara", hace que el resto del código sea mucho más legible (y de paso hacerlo más compacto, sencillo y eficiente).
Sobre el ejemplo de los PoC en seguridad... bueno, yo también llevo varios años en seguridad informática, así que no me pilla de nuevo Me imagino que lo has hecho como acto de divulgación para el público
Por último, no te tomes como algo personal cuando alguien critique tu código, es la mejor manera de aprender cosas nuevas. Cuando yo era más joven y estaba aprendiendo (joder qué mal suena esto) también me tomaba las cosas mucho peor que ahora. Ahora veo lo mucho que me faltaba por aprender... y me doy cuenta de cuánto me queda aún
"los números de ese captcha, siempre salen en la misma posición, tamaño y medida, además del mismo color y misma fuente"
Sin duda el que ha 'roto' este sistema es todo un Jaquer! con tanta dificultad parecia imposible que nadie lo consiguiera... next stage: Hola mundo multithread.
#20 Pero en un site de promoción de noticias GENERAL debería de utilizar jergas más entendibles por la plebe, o al menos, realizar el esfuerzo de intentarlo. A portada va a llegar igual, siempre que el código sea de linux o menéame; pero al menos una parte pequeña de la minoría de gente que lee los artículos antes de menearlos la entenderían.
Comentarios
No es importante que sea el de menéame o cualquier otro. Es interesante ver la forma de resolver el problema que adoptó el autor.
Para aquel que no entienda, la idea es "escanear" todos los puntos de una misma línea (la 20). El color se expresa en RGB, sistema en el cual el rojo, el verde y el azul pueden tomar valores de 0 a 255, para formar muchísimas combinaciones. El color blanco es la suma de todos los colores, entendiéndose por eso rojo = 255, verde = 255, azul = 255. De esta forma, y teniendo en cuenta que en el fondo (naranja) las tonalidades azules son bastante pequeñas, deduce que cualquier pixel con valor azul > 100 es "blanco", o sea, parte de un dígito.
Desde ahí es fácil ver que cada número está formado por combinaciones de píxeles diferentes, y que incluso una línea alcanza para distinguir un 3 de un 4, por ejemplo.
#7 http://fon.gs/omg_solo_n_meneos
]
[Mira que hace tiempo que no lo ponía
¡Meneame se rompe! (Por lo menos el captcha)
#11 ¿Quejarse sobre los votos de los demás se ha convertido en el comentario cansino por excelencia? ¿Se convirtió ya hace tiempo?
#4 ¿acabar pasando?
En una ocasión estaba en un tren hablando con un colega sobre una demo que había visto en la que se utilizaba una rutina para rellenar vectores. La rutina era tan rápida que rellenaba los vectores en tiempo real mientras la figura giraba y temblaba como si fuera de gelatina. Los llamábamos Glenz Vectors. Un señor que iba en el tren nos preguntó que de donde éramos.
-De málaga.
-No... pero.. digo ¿donde nacisteis?
-... En Málaga.
-¿Y donde os habéis criado?
-...Aquí en Málaga.
-Es que... no puede ser. Habláis muy raro. Yo soy de Málaga y nunca he oído a nadie hablar así. Usáis unas palabras mu raras. En serio, ¿de donde sois?
_______________________________________
Esta conversación tuvo lugar hace 20 años.
¿Acabar pasando? Ya pasó, ha pasado siempre. Igual que si se ponen a hablar dos médicos o dos Albañiles. Fuera de su gremio poca gente los entenderá.
C-C-C-CAPTCHA BREAKER!!1
"El caso es que estoy ayudando a mi novia a entender C/C++, sistemas y todo eso, así que decidí que hoy programaría algo con ella (algo simple,para empezar)"
Como informático que soy, horrorizado me hallo. ¿No tienes mejores cosas que hacer con ella que enseñarle a programar?
#4 ¿Acabar pasando? Si ha sido toda la vida sí. Yo hay veces que me pongo a hablar con mis compañeros en la Universidad y me doy cuenta de que una de cada cinco palabras son siglas raras. Ejemplo práctico:
"El otro día estuve aprendiendo XSLT para generar XHTML. Las DTD dieron problemas, pero bueno. Con CSS puedes definir el estilo y hasta el layout, con DIVs. También miré XPath, para acceder al DOM desde JavaScript. Si es que, aunque me guste más YAML, el XML no está mal del todo..."
#11, go to #6
esta noticia es "divulgativa total"...tengo una pregunta: ¿a los informáticos y 'weberos' les acabará pasando como a los críticos de arte, que no hay quien les entienda?
#48: Pero es que la aritmética binaria ya sería un nivel superior. Primero tienes que aprender cosas sencillitas: IF, SWITCH, sumar, restar, funciones, valores float e int... Luego cuando controlas eso ya pasas a punteros, aritmética binaria, y demás historias.
Por supuesto que lo que pones es sencillo, pero para aprender un lenguaje, no ayuda nada, porque te obliga a pensar en muchas coass al mismo tiempo en lugar de concentrarte en lo que realmente quieres aprender.
#28: Que quieres que te diga, pero para principiantes está genaial. Yo he visto algún código fuente de programas más o menos serios, y no me entero de mucho, están llenos de constantes, enumeraciones, funciones para todo... En cambio, ese programa, si lo he entendido bien, no tengo que estar de un lado para otro.
Primero cargas la imágen JPEG, luego te vas a la linea del medio y punto por punto vas cargando un vector de 7 elementos. Y cada vez que metes 7 elementos en el vector, comparas el vector con diferentes patrones con la función de más arriba. La función también se encarga de escribir en pantalla.
Además, el código espagueti es cuando se abusa de GOTO, no cuando metes "números mágicos" y demás.
Quizás se eche de menos algún comentario explicando los "números mágicos" en la linea donde están (no al principio), y las funciones, pero yo creo que es un programa bastante claro.
#30: Eso que propones de mejorar la memoria, es contraproducente. Si, ganas memoria (¡7 bytes!) pero a cambio tienes que meter algo de complejidad al programa, aumentas el riesgo de meter errores (bugs), y sobretodo, lo que ganas en memoria lo pierdes en tiempo de proceso, al incluir sentencias extra. Tampoco es que sea mala idea lo que propones (es más, se agradece que la gente haga aportaciones), pero yo creo que no merece la pena.
#25 Pero si no tienes ni idea de lo que estamos hablando, te dará igual que lo llamemos de una forma u otra, que usemos una jerga u otra. Si no sabes lo que es CSS, poco te importará que lo llamememos CSS o hojas de estilo en cascada.
La cuestión no es la jerga, la cuestión es que quizás no expliquemos en detalle cada concepto. Por ejemplo, al hablar de CSS podría poner entre paréntesis que es un documento de texto vinculado a una página web que fija el estilo de la misma.
Pero la verdad es que carecería de sentido explicar cada concepto que una persona sin conocimientos de informática desconociese, ya que el público al que escribes es informático y conoce esos términos.
Y menéame es un site de promoción de noticias GENERAL específicas. Es decir, tienen cabida en él todo tipo de temáticas, con noticias más o menos específicas. Y el hecho de que se incluyan noticias generalistas, no significa que no se puedan incluir noticias de temática técnica, ya que mucha gente de la comunidad disfruta viéndolas, como es mi caso.
¿Y si lo hacemos en ensamblador o en máquina?
#4 eso parece
Pues a mi no me gusta nada el codigo....
Veo codigo espagueti y que no se respeta el principio DRY -y estas son dos cosas que me duele ver-
No veo apenas comentarios ni nombres lo suficientemente descriptivos. ('checkNumber' es una funcion que, como su propio nombre indica, dibuja un numero por pantalla dependiendo de la posicion en la que este un 1 -si es unico- en un array... )
Veo 'numeros magicos' que no se de donde salen z=22? z
#19 Hay tiempo para todo, el problema es la procrastinación, se nota que eres informático
#35 me malinterpretas:
No me referia a ti, me referia al codigo que hay actualmente en la pagina (esos ifelses anidados de 8 clausulas horribles). El switch que pones me parece lamentablemente inevitable (snif) y tu solucion me parece inmejorable, bueno, solo mejorable con tabulaciones. (ya se que se habran prerdido por el camino, es que es la unica cosa que seria capaz de criticar).
Sobre lo del entero evidentemente me parece mejor en todos los sentidos menos en el didactico.
Me parece que es mas visible por una persona que no sabe ver los unos y ceros como numeros decimales que como una secuencia de bits. Solo digo que realmente en el fondo tu solucion (secuencia de unos y ceros) y la de la pagina (array de numeros que solo pueden ser uno o cero) son el mismo en concepto pasa que el autor piensa que es mas facil explicarle el concepto a un lego dispuesta la informacion de ese modo.
Pero solo es una opinion personal.
Nunca criticaria tu codigo (ni pisaria la cuerda de un/a escalador/a)
#2 Siento curiosidad ¿Porqué no escribes la letra "i"? ¿Teclado roto?
jcarlosn majete:
Yo desde el primer momento asumo que es un ejemplo para alguien que no sabe programar, e incluso entiendo el mecanismo para llegar a escribir eso. Me parece una buena manera de explicarlo a un lego en la materia como tu novia contigo al lado.
Pero no es muy buen codigo... y no me parece un ejemplo para aprender a programar para alguien que no sea tu novia a la que tienes al lado como decia #10 que es lo que he comentado en un ppio. Quiero decir: si tuviera que hacer un tutorial para que la gente aprendiera a programar no lo usaria...
Mierda no se si se me entiende... a estas horas solo tengo ganas de beber... me desdigo y me piro.... continuarmos con el flame del spaguetti western
PD: Mola eso de enseñar a programar a la novia, lo voy a hacer yo con la mia, pero no usare C: DEGENERAO!
#54 Estás sugiriendo hacer una lookup table y una tabla hash para ahorrarte un bloque de 7 ifs o un switch con siete cases?
Y todo ello, para un PoC de 4 lineas?
Estas cosas solo se leen en meneame
#36 Perdona, había malinterpretado tu comentario. De todas formas, gracias por lo de inmejorable Lástima que se pierda la indentación cuando envías un mensaje. Se me ocurren maneras de hacerlo más eficiente, como usar una lookup table para guardar las representaciones binarias y hacer que checkNum sea O(1), pero eso ya es pasarse.
#28 Yo entiendo que ha sido un programita hecho a prisa y corriendo. Sin embargo hay algunas cosas que me preocupan y que ya no tienen que ver con la prisa, sobre todo el uso de un array de enteros para guardar valores 0/1 (bits al fin y al cabo) en lugar de usar un único char y aplicar aritmética binaria.
Le he dejado un comentario en el blog explicando cómo mejorar la eficiencia, reducir el uso de memoria y aumentar la legibilidad del código, supongo que no tardará en aprobarlo.
#31 Creo que es curioso que critiques la solución que le he enviado... si todavía no ha aprobado el mensaje
Precisamente el ahorro que propongo hace que vaya más rápido y reduzca la complejidad y, de rebote, haga el código más legible. Dime qué bug y complejidad añado si, en lugar de tener un array de 8 enteros (donde cada uno ocupa 4 bytes en un procesador i386, es decir 32 bytes), hago esto:
unsigned char positivos = 0;
...
// bucle que escanea las líneas
...
// Vamos añadiendo "por la cola" los resultados de comprobar si color
// mayor que 100 o no (1 si lo es, 0 si no).
positivos = positivos 100);
Memoria ocupada: 1 byte. Además, en la función checkNum sólo es necesario un bloque switch...case que compruebe "positivos". Habiendo definido las constantes como los valores decimales de la representación binaria, el código queda así:
void checkNumber(unsigned char positivos, int check) else
break;
case TWO:
printf(”2″);
break;
...
// continúa
}
Resultado final: menor complejidad, más eficiencia, menor consumo de memoria y, además, más legibilidad (porque no me negarás que tener que leer un if con 8 cláusulas no es lo más legible del mundo).
Mola, jcarlosn, creo que tienes un fan, Ap0 espero que no se vuelva como http://en.wikipedia.org/wiki/Mark_David_Chapman Curioso que haya votado en contra de mi último comentario, no creo que haya insultado a nadie y he argumentado (todo lo bien que he podido) mi opinión.
Con este comentario, creo que me he ganado una Buambulancia: http://buaaacacharros.wikispaces.com/Buaaacacharros
Exacto #52, gracias por aclararlo, es lo que intentaba decir todo el rato
#45 Han habido muchos códigos antes que este, hombre, mas básicos al principio, etc, este no ha estado mal.
La curva de aprendizaje de C es bastante fuerte (yo no he elegido enseñarle C, ella ya sabia un poco, muy poco, de la uni), primero hay que pelearse con el manejo de la memoria, stack, heap (memoría dinámica), etc y luego, pelearse con interpretaciones de esa memoria (casts) y luego con apuntadores a esa memoria (punteros) y es todo un gran lío, si mientras intentas que alguien comprenda BIEN y a fondo el manejo de memoria, empiezas a comerle la olla con que un bloque de ifs puede ser sustituido con 8 bits y operaciones a nivel de bits, esto es contraproducente.
Yo creo que es bastante fácil de entender el problema:
Si yo te enseño X, mientras te enseño X surge Y y salto a Y, y entonces surge Z y salto a Z, la persona no aprende NADA, y desde luego, espero que no os tengáis que ver en la tesitura de enseñar C a alguien, por que no es una tarea sencilla, es mil veces mas fácil enseñar java o python, si es que puedes elegir, claro.
Pero bueno, que cada uno ve la forma de enseñar a su manera, y evidentemente, el como enseñar, también radica mucho en quien es la otra persona y como es, que capacidades tiene, que base tiene, y cual son sus puntos fuertes y flojos, por eso no tiene sentido aquí juzgar como enseño a mi novia a programar, no llegariamos a ningún lado con esta conversación.
El código y la explicación queda ahí, nadie ha dicho que sea un super código, es un PoC del estilo de #46.
Por cierto #31:
Lo de spagetti code tambien se aplica a if-elses anidados en if-elses anidados en.... switches etcetera... Son elementos de control que hacen el codigo farragoso y dificil de seguir. Al menos yo siempre lo he usado en ese sentido...
Y otra cosa muy mala del codigo:
Para enseñar a programar a tu novia usa python o asi... pero C... degenerado! luego nos dejan y nos quejamos!!!
Bueno, me han gustado mucho los comentarios, mola ver que no siempre nos encontramos los mismos en los mismos flames, sino que a veces son charlas constructivas. (a alguien le puse un negativo sin querer, quería ser un positivo, lo siento!).
Sin embargo hay una cosa en la que discrepo enormemente con vosotros... y es el tema del spagueti code, simplemente, yo no veo el código espagueti en ningún sitio, es así de simple.
Este tipo de código se conoce como PoC (proof of concept, o en castellano, prueba de concepto), los PoC se caracterizan por ser pruebas rápidas a problemas de seguridad.
Voy a poner un ejemplo, se encuentra un bug en el servicio X, normalmente alguien crea un programa que lo explota (exploit), ese programa no se hace siguiendo un procedimiento de rational, creando uml's etc etc, luego creando 'use cases', programandolo, depurandolo y perfeccionandolo, nada mas lejos.
Por que no? por que sería ridículo, es una PRUEBA DEL CONCEPTO, no un programa en producción.
Pero como esto no ha derivado en un flame sin sentido, voy a explicar un par de cosas, por que ya que os habéis puesto en plan crítico, en un código que he intentando simplificar para mi novia, vamos a profundizar en el tema:
1. El problema de los ifs tal como se ha dicho arriba se puede solucionar con aritmetica binaria, y aquí a todo el mundo se llena la boca con ello, bien, vale, creeis REALMENTE que esto es legiable para alguien que está aprendiendo?:
positivos = positivos 100);
Super legible, si señor.
Eso es completamente ILEGIBLE para alguien con poca experiencia en la materia, no por que no sepa aritmetica binaria, sino por que si a alguien que anda al limite haciendo un programita de prueba, le agregas eso, lo matas, su cerebro explota ya, por eso, hay que ir por partes.
Sin embargo, como a todo el mundo se le llena la boca con esta solución voy a comentar un par de cosas a #32:
un array de 8 enteros (donde cada uno ocupa 4 bytes en un procesador i386, es decir 32 bytes),
http://en.wikipedia.org/wiki/Integer_(computer_science)
Un entero ocupa 32bits, no 32bytes, pero me imagino que esto ha sido un tipo
Aparte de esto, afirma que tu unsigned char mide 1bytes, como lo sabes? No es siempre así en todas las arquitecturas, por eso al hacer malloc para almacenar 32 chars no se hace:
char *cadena = (char*)malloc(32);
Sino:
char *cadena = (char*)malloc(sizeof(char)*32));
Citando a wikipedia:
http://en.wikipedia.org/wiki/Byte
A datatype or synonym for a datatype in certain programming languages. C and C++, for example, defines byte as "addressable unit of data storage large enough to hold any member of the basic character set of the execution environment" (clause 3.6 of the C standard). Since the C char integral data type must contain at least 8 bits (clause 5.2.4.2.1), a byte in C is at least capable of holding 256 different values (signed or unsigned char does not matter). Various implementations of C and C++ define a "byte" as 8, 9, 16, 32, or 36 bits[4][5]. The actual number of bits in a particular implementation is documented as _CHAR_BIT_ as implemented in the limits.h file.
Va bien esto para no olvidar nunca que char != byte en C, siempre hay que mirar el sizeof o bien la constante de limits
Pero bueno, habiendo explicado el por que del bloque de los ifs, que creo que cualquiera que enseñe a otra persona a programar, entenderá por que no he agregado las operaciones a nivel de bits.
Yo creo que todas estas explicaciones, sobre si char es un byte realmente o no lo es, sobre si operaciones a nivel de bits hubiesen sido mejores o no...no son el momento para la persona a quien intento ayudar a en sus estudios (estudia informática)
Este código fue hecho para enseñar, para probar la libjpg y poco mas, nadie debe entenderlo como código en producción.
Lo que no entiendo es el motivo de ponerse a analizar un PoC como si de un código stable y en producción se tratase, al final no se ha creado flame, y es bonito, pero por que al final tenemos que andar midiendonosla siempre de meneo en meneo, a ver quien la tiene mas grande? Es ridículo.
Si queréis, como ejercicio divertido, un día creamos cada uno un pequeño código stable para algo, y nos la medimos bien, hombre
P.D. al ser un PoC y encima para ayudar a alguien a dar sus primeros pasitos, el código tiene MUCHISIMOS fallos mas, y además mucho mas graves
#30 los comentarios en rooibo se aprueban solos, no se que habrá pasado, voy a mirar en akismet
#40: Si no te digo que no sea una solución mejor, pero a mi, lo primero que se me habría venido a la cabeza es esa solución, puesto que me parece más fácil de programar y de pensar al principio. Luego, con esa solución delante de mis ojos funcionando, podría ocurrirseme la tuya, pero lo primero que se me vendría a la cabeza es lo del autor.
Piensa que lo que haces es "si esto es como lo otro, tal, y sino...tal tal tal..." es decir, primero piensas en IFs. A mi no me parece tan mala la solución que propuso el autor, una cosa es que sea mejorable, y otra que lo tachen de código espagueti y malo a la primera.
#30 a mi me parece mas de 'deprisa y corriendo' la aritmetica binaria que el tema DRY y spageti.
Creo que una cosa me duele a los ojos y convierte el codigo en ilegible y lo otro es una licencia para que su interlocutora lo entienda mejor, que, aunque sea una burrada en temas de rendimiento, veo a menudo -de hecho yo eso lo empece a utilizar cuando trabajaba en moviles que necesitabamos cada bit. En J2EE, que es lo que mas se hace, seguramente no influya mucho... se compra otro servidor y ya esta! (lo he visto hacer)-...
Diferencia de apreciaciones. Pero en fin.... mola.
#15 pues a mí esa conversación me parece normal entre desarrolladores web. Todos los gremios tienen sus argots, jergas y palabras que sólo ellos usan.
Gracias por este código. Es bastante interesante el programita!
#56 ¿Es una prueba de concepto de cómo se usa la libjpeg o un ejercicio para enseñarle a tu novia a programar? Si es lo segundo puedes aprovechar para, en la siguiente iteración del programa, enseñarle a calcular límites asintóticos y a utilizar estructuras de datos. Es mejor que lo vea en un algoritmo sencillo como ese que no en uno mucho más complejo.
Supongo que será un error, pero no se trata de crear una lookup table y una tabla de hash, sino que lookup table es un concepto y la tabla de hash la estructura para implementar esa idea. Una lookup table puede ser también un array, una lista o un árbol.
Por cierto, puedes aprovechar ahora y enseñarle a liberar la memoria reservada por el malloc y a cerrar los descriptores de ficheros
#55 Meter, meter, meter.... siempre pensando en lo mismo.
#54: Claro que si, pero primero hay que saber como funciona un ¡Hola mundo!
Luego, empiezas a ver la aritmética normal, las funciones de entrada y salida scanf y printf.... algo así: printf("bla %i n", 4*5+3);
Luego metes las variables y ya empiezas a hablar de como van los tamaños...
Luego metes los IF, SWITCH...
Y sigues metiendo.
Sobre si C es difícil para principiantes, a mi no me lo parece si se enseña bien, por orden y sin meter muchos conceptos nuevos a la vez.
Yo sigo en mis trece, y viendo esta noticia en portada no tengo mas remedio que hacerme unas preguntas que lanzo solo como reflexión sobre el funcionamiento de meneáme.
¿De verdad el como romper un captcha que ya no se usa, es lo suficientemente interesante para llegar a portada?
¿Cuantos de los que han votado saben lo suficiente de programación, para saber si lo que se dice es correcto?
Resumiendo:
¿hablar de meneáme, se ha convertido en una garantía de portada?
#26 Gracias por los negativos, recomiendo a los que los han hecho que se compren un detector de ironías.
No entendo nada.
Para que veáis que no me tiro el rollo con lo de PoC (Proof of concept) aquí teneis un ejemplo típico de milw0rm:
http://www.milw0rm.com/exploits/6407
#50 Ap0 es mi novia, irónico el negativo
#48 lo siento, pero la aritmetica binaria la aprendí hace muchos años![:lol: lol](https://cdn.mnmstatic.net/v_149/img/menemojis/36/lol.gif)
Bromas aparte, claro que no me lo tomo a mal, pero es que no es mi código
Los pasos han sido así:
1. propongo algo ameno que programar a alguien que aprende, romper el captcha este, que es bastante sencillo
2. lo programamos, vamos haciendo partes y hablando las cosas
3. queda un PoC bastante cutre, lo repasamos un poco
4. queda un PoC normalillo, lo publicamos como divulgación
Pero no me ha molestado tu comentario, seguramente, yo hubiese hecho lo mismo, es algo normal, por eso he querido aclarar que se trata de un PoC realizado como ejercicio de practicar un poco el C, pero liberado como ejemplo, por si a alguien le sirve, como mínimo para ver la jugada con libjpeg.
Vaya, que no hay mal rollo, es mas, ojala mi novia lea tu comentario, y aproveche para preguntarme, y un día de estos le explico un poco mas, y hacemos una versión mejorada y mas decente
No encuentro el "captcha" ese en el diccionario.
#11 no se usa en meneame, pero si en los clones... lo que permitiría atacarlos con spam. Eso afectaría a ciertos clones muy interesantes, en el caso que no usaran el mismo sistema que usa ahora Meneame.
mmm
#27 Si hawkings consiguió publicar un libro de divulgación científica sobre la creación del universo medianamente entendible, impossible is nothing. Como ya dije, lo primero son las ganas.
PD. Soy estudiante de ingeniería informática. No hablo por mí.
Edito de nuevo:
Si sustituyeras "x*3*cinfo.output_width" por una variable temporal, y la asignaras su valor antes de entrar al bucle iría un poco más rápido. Es un detalle sin importancia que digo como curiosidad, porque es un programa muy interesante para aprender.
#52 y #53 Yo creo sin embargo que, puesto que lo que se va a programar es un ordenador, hay que saber al menos un poco de la teoría de cómo representa la información por dentro. De todas formas, en el código hay un puntero y un malloc, cosas que creo que son más difíciles de entender que sumar, restar o desplazar números (binarios, en este caso).
También creo que no se le da tanta importancia a temas más "teóricos" como la algoritmia (cálculo del orden, estructuración, etc.), por ejemplo, si usas una lookup table y una tabla de hash puedes hacer que sea O(1) o que al hacer lo "raro" de los números, el número de comprobaciones se reduce a 10 (o menos).
#22 en fin
#39 Pues si alguien se pone a programar sin saber utilizar lo mínimo del sistema binario, su representación y las operaciones que puede hacer, mal vamos. Por ejemplo, en un post de la programadora principal de Pownce:
http://leahculver.com/2007/04/19/star-ratings/
demuestra que no sabe lo más mínimo de aritmética (no ya binaria) ni de algoritmia. Parece poco importante, puesto que los procesadores actuales son muy rápidos, pero el código original es excesivamente complejo.
La mayor ventaja que le veo a mi solución es que hace el código más legible, puesto que puedes comparar directamente la constante ZERO (11000011 en binario, 195 en decimal) con el valor de la variable "positivos", mientras que en la solución original hay que comparar cada una de las posiciones del array.
Lo peor de todo es que no estoy hablando de una representación compleja, sino de algo fundamental (el sistema binario) que debería estar grabado a fuego en la cabeza de todos los programadores.
#34: ¿Difícil de seguir?
Si es sencillísimo, se ve muy claro: si no es esto, vamos a probar esto otro, si tampoco lo es, probamos esto otro, si tampoco lo es...
Vamos, yo lo veo más claro que si se hubiera hecho una función que evitara repetir el código.
#32: Si, tienes razón, es más eficiente, aunque es más complejo de ver, y te juegas más meter un error si eres principiante. El ahorro de memoria es insignificante hoy en día, pero no está mal saber ese detalle para proyectos más grandes donde si se note el ahorro.
#33 y #34 Pues sinceramente, creo que es un error grave pensar que para representar un conjunto de bits haya que usar un array de enteros. No ya por eficiencia (total, con los procesadores que tenemos y la cantidad de memoria, para un programita así de pequeño no merece la pena sacarle hasta la última gota), sino por legibilidad. Cualquier buen programador debe tener por la mano todas estas cosas de representaciones binarias, algoritmia, etc.
De todas maneras, si consideras que un if dentro de un switch...case (como el de mi solución) es código spaghetti, ya me dirás cómo solucionarías el mismo problema (que un mismo valor pueda representar dos soluciones distintas y que necesite una segunda comprobación).
#43 1. El problema de los ifs tal como se ha dicho arriba se puede solucionar con aritmetica binaria, y aquí a todo el mundo se llena la boca con ello, bien, vale, creeis REALMENTE que esto es legiable para alguien que está aprendiendo?:
positivos = positivos 100);
Super legible, si señor.
Sé que puede parecer intransigente, pero si esa persona no entiende una cosa tan sencilla, entonces no está preparada para programar aún. Luego nos quejamos de que se enseñan demasiadas mates. De todas formas, puedes usarlo para enseñarle aritmética binaria, ¿no crees? Por otra parte, he puesto un comentario para aclarar lo que hacía, aunque tal vez no sea el más claro del mundo
un array de 8 enteros (donde cada uno ocupa 4 bytes en un procesador i386, es decir 32 bytes),
en.wikipedia.org/wiki/Integer(computer_science)_
Un entero ocupa 32bits, no 32bytes, pero me imagino que esto ha sido un tipo :-P
Nope, no ha sido una equivocación, 4 bytes * 8 enteros = 32 bytes, pensaba que era suficientemente claro. De todas formas el enlace a lo que es un byte... bueno, ha sido didáctico
Va bien esto para no olvidar nunca que char != byte en C, siempre hay que mirar el sizeof o bien la constante de limits :-)
De http://en.wikipedia.org/wiki/C_variable_types_and_declarations:
char The most basic unit addressable by the machine; typically a single octet. This is an integral type.
No sabía que (no te lo tomes a mal, anda ;-))
[ironic mode on]
a) hubieras pensado el programa para arquitecturas de 16 bits
b) hayas estado ejecutando el programa en un Linux en 16 bits (ya sé, ya sé, ELKS)
[ironic mode off]
es decir, que el char es el tipo de dato más pequeño para la arquitectura en la que programabas y además, es suficiente para almacenar TODA la información que necesitas.
Mi opinión es que es línea tan "rara", hace que el resto del código sea mucho más legible (y de paso hacerlo más compacto, sencillo y eficiente).
Sobre el ejemplo de los PoC en seguridad... bueno, yo también llevo varios años en seguridad informática, así que no me pilla de nuevo Me imagino que lo has hecho como acto de divulgación para el público
Por último, no te tomes como algo personal cuando alguien critique tu código, es la mejor manera de aprender cosas nuevas. Cuando yo era más joven y estaba aprendiendo (joder qué mal suena esto) también me tomaba las cosas mucho peor que ahora. Ahora veo lo mucho que me faltaba por aprender... y me doy cuenta de cuánto me queda aún
¡38 meneos y en portada!
"los números de ese captcha, siempre salen en la misma posición, tamaño y medida, además del mismo color y misma fuente"
Sin duda el que ha 'roto' este sistema es todo un Jaquer! con tanta dificultad parecia imposible que nadie lo consiguiera... next stage: Hola mundo multithread.
No he podido resistirme... ¿Captchowned?
#20 Pero en un site de promoción de noticias GENERAL debería de utilizar jergas más entendibles por la plebe, o al menos, realizar el esfuerzo de intentarlo. A portada va a llegar igual, siempre que el código sea de linux o menéame; pero al menos una parte pequeña de la minoría de gente que lee los artículos antes de menearlos la entenderían.
Eso pasa por usar la GPL esa.
no tengo karma suficiente para enviar noticias, por favor voten positivo.