tag:blogger.com,1999:blog-77903100440376052522024-03-13T03:35:32.747-07:00AlbertoBSD♒ Programador, Economista, Geek, Tapatio, Webmaster, ✌ Historias #USMX3 #TSHOAH ♻ #HIYC823. Experiencias, Android, iPhone y masalbertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.comBlogger124125tag:blogger.com,1999:blog-7790310044037605252.post-8479459312425191032019-03-28T04:20:00.002-07:002019-03-28T04:20:46.956-07:00Es el universo un punto de longitud infinitesimal <br />
Esa es la pregunta, ¿Es nuestro universo un punto de longitud infinitesimal? entiéndase:<br />
¿Tiene longitud 0 nuestro universo?<br />
¿Es nuestro universo una singularidad?<br />
<br />
<h3>
<b>Relatividad general</b></h3>
Según los postulados de la Relatividad Especial[1] tenemos que:<br />
<br />
<ol>
<li>Las leyes del universo son las mismas sin que importe el marco de referencia inercial.</li>
<li>La Luz siempre se propaga en el vacío con una velocidad constante c que es independiente del estado de movimiento del cuerpo emisor y del estado de movimiento del observador. </li>
</ol>
En nuestro marco de referencia inercial y con nuestras leyes físicas actuales, observamos un universo en expansión acelerada donde todas las galaxias se alejan unas de otras, quedando solo grupos de galaxias locales que se atraen entre si.<br />
<br />
En nuestro marco de referencia tenemos "acceso" a un universo observable con un diámetro de 93 mil millones de años luz de distancia.<br />
<h3>
<b>Contracción de la longitud.</b></h3>
Conocida como Contracción de Lorentz[2], es un efecto relativista que consiste en la contracción de la longitud de un cuerpo en la dirección del movimiento a medida que su velocidad se acerca a la velocidad de la luz.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="about:invalid#zClosurez" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" src="data:image/png;base64,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" /></a></div>
<br />
Supongamos que tenemos una nave espacial con tecnología capaz de viajar a velocidades "cercanas" a la de la luz. Vamos a utilizar dicha nave para viajar desde la Via Lactea en nuestro sistema solar hasta un planeta ubicado en el centro de la Galaxia de Andromeda.<br />
<br />
Desde el Marco inercial de referencia de un habitante en la tierra, la distancia (L0) a la dicho planeta es de digamos <span class="LrzXr kno-fv">2600 Millones de años luz.</span><br />
<br />
Desde el Marco inercial de referencia de la nave espacial viajando a una velocidad de 0.9c (90% la velocidad de luz) la distancia recorrida (L1) es, según la ecuación de lorentz de alrededor de 1134 años luz.<br />
<br />
Mejoremos nuestra nave y viajemos a 0.98c (98% de la velocidad de la luz) y desde nuestro marco de inercial de referencia la distancia L1 recorrida es cercana a 517 Millones de años luz.<br />
<br />
Sin embargo no nos va alcanzar la vida a esa velocidad, tenemos que mejorar nuestra nave aun mas, viajemos a una velocidad de .999999999999999c y a esa velocidad la distancia L1 recorrida es de tan solo 116 Años Luz,<br />
<br />
Si seguimos incrementando la velocidad de nuestra nave imaginaria podemos llegar una distancia L1 muy pequeña. Digamos que podemos llegar una distancia L1 de 30 centímetros que la luz podría recorrer en un nanosegundo<br />
<h3>
<b>El marco inercial de referencia de un fotón o onda de luz.</b></h3>
<br />
Supongamos que viajamos la misma distancia L0 del ejemplo anterior, pero ahora lo realizamos en un fotón u onda de luz, en nuestro nuevo marco de inercial de referencia la distancia L1 recorrida podría no estar determinado ya que o es 0, o es un valor muy cercano a 0 considerando el principio de indeterminación de heisenberg.<br />
<br />
Desde el Marco Inercial de Referencia de un observador en la tierra la distancia L0 es inmensa, pero desde el marco de referencia de luz esta distancia L1 es infinitesimal.<br />
<br />
<h3>
<b>Una acción Fantasmal a distancia</b></h3>
Según comento Albert Einstein sobre el Experimento mental EPR en el Entrelazamiento cuántico no podia existir esa "transmisión" instantánea de información entre las partículas, considenrandolo una acción fantasmal a distancia por violar el Realismo Local.<br />
<br />
Entonces para los "observadores" humanos del experimento EPR existe una distancia L0 entre las particulas, Sin embargo considerando el marco inercial de referencia de las partículas en el mismo experimento mental, cualquier distancia que exista entre ellas, es una distancia L1 y debera de ser 0 o un valor infinitesimal, por lo cual la información del estado de una partícula A, puede afectar de forma Instantánea a una partícula B.<br />
<h3>
<b>El tamaño de nuestro universo Observable</b></h3>
Según nuestro marco inercial de referencia y con nuestras leyes de física actuales podemos medir un universo observable de distancia L0. Una distancia inmensa. <br />
<br />
Desde el marco inercial de referencia de luz, la longitud del universo es L1 un valor de 0 o infinitesimal, una singularidad.<br />
<br />
¿En el marco de referencia de la luz existe la distancia? ¿O solo es una sopa de partículas cambiando de estado a otro, afectando el estado de todas las demás partículas?<br />
<br />
<h3>
Experimento: Universo de 2 partículas.</h3>
Supongamos que el universo existen 2 partículas (A y B) de longitud infinitesimal, separadas por una distancia L0 para el marco inercial del observador mental de estas partículas, estas partículas viajan en direcciones opuestas entre si a la velocidad de la luz, cada una cantidad de masa indeterminada para este experimento por lo tanto estas partículas tienen densidad infinita. Las partículas podrían estar girando sobre su propio eje o no estarlo.<br />
¿Atre la partícula A gravitacionalmente a la partícula B? y ¿viceversa?<br />
<br />
<br />
<br />
<h3>
Referencias</h3>
<br />
[1] Relatividad Especial - <a href="https://es.wikipedia.org/wiki/Postulados_de_la_Relatividad_Especial">https://es.wikipedia.org/wiki/Postulados_de_la_Relatividad_Especial</a><br />
[2] Contracción de Lorenz - <a href="https://es.wikipedia.org/wiki/Contracci%C3%B3n_de_Lorentz">https://es.wikipedia.org/wiki/Contracci%C3%B3n_de_Lorentz</a><br />
<br />albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-52492498967368254572018-11-30T11:52:00.002-08:002018-11-30T11:52:54.994-08:00FIFO en C Primero en Entrar, primero en salir, Cola o Fila <span style="font-size: large;">No es lo mas eficiente, hay muchas cosas se podrian mejorar, en
especifico la forma en la que se organizan el arreglo de elementos
actuales en la Fila, sin embargo funciono para el proposito.<br /><br />Yo
se que la mayoría de estas estructuras ya están implementadas. Pero no
se puede decir que eres programador si no sabes implementarlas por tu
cuenta.</span><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: large;"><a href="https://2.bp.blogspot.com/-6vAxfhCQK-w/XAGUQu3bhiI/AAAAAAAAYF8/5FRAai0qgLAeqGf-yp6EP_nT3ZWgaP2swCLcBGAs/s1600/vE0c5nr.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="247" data-original-width="377" height="209" src="https://2.bp.blogspot.com/-6vAxfhCQK-w/XAGUQu3bhiI/AAAAAAAAYF8/5FRAai0qgLAeqGf-yp6EP_nT3ZWgaP2swCLcBGAs/s320/vE0c5nr.png" width="320" /></a></span></div>
<br />
<span style="font-size: large;">Codigo:</span><br />
<br />
<span style="font-size: large;">/*<br /> El tipo de dato se puede cambiar dependiendo de la implementacion que se le quiera dar, tambien se tendrian que cambiar los tipos de datos devueltos por las funciones<br /> En este caso yo queria un arreglo de apuntadores char* por lo cual el contenedor es char**<br /> */<br /><span style="font-family: "Courier New", Courier, monospace;"><br /><br />typedef struct str_queue {<br /> char **queue;<br /> int len;<br />}Queue;<br /><br /><br />Queue *create_queue();<br />void free_queue(Queue *q);<br />char *de_queue(Queue *q);<br />void en_queue(Queue *q, char *ptr);<br /> <br /><br />Queue *create_queue() {<br /> Queue *r = malloc(sizeof(struct str_queue));<br /> r->len = 0;<br /> r->queue = NULL;<br /> return r;<br />}<br /><br />void free_queue(Queue *q) {<br /> if(q) {<br /> if(q->queue)<br /> free(q->queue);<br /> free(q);<br /> }<br />}<br /><br />void en_queue(Queue *q, char *ptr) {<br /> q->queue = realloc(q->queue,(q->len+1)*sizeof(char*));<br /> if(q->queue != NULL) {<br /> q->queue[q->len] = ptr;<br /> q->len++;<br /> }<br />}<br /><br />char * de_queue(Queue *q) {<br /> char *r = NULL;<br /> if(q->len >= 1) {<br /> r = q->queue[0];<br /> memcpy(q->queue,q->queue + 1 ,sizeof(char*)*(q->len-1));<br /> q->len--;<br /> q->queue[q->len] = NULL;<br /> }<br /> return r;<br />} </span></span><br />
<br />
<br />
<span style="font-size: large;">Yo en su momento lo utilize para un post, donde realizaba una versión
iterativa y necesitaba almacenar en una Cola el listado de los
directorios que aun faltaba por recorrer:<br /><br /><a href="https://foro.elhacker.net/programacion_cc/problema_de_memoria_con_readdir_solucionado-t490167.0.html">problema de memoria con readdir (Solucionado)</a><br /><br />Ejemplo de uso:</span><br />
<br />
<span style="font-size: large;"><span style="font-family: "Courier New", Courier, monospace;">Salida#include<stdio.h><br />#include<stdlib.h><br />#include<string.h><br />#include<time.h><br /><br />int main() {<br /> char *cadenas[10] = { "Cadena_0","Cadena_1","Cadena_2","Cadena_3","Cadena_4","Cadena_5","Cadena_6","Cadena_7","Cadena_8","Cadena_9"};<br /> char *actual;<br /> int index1,index2,i =0;<br /> srand(time(NULL));<br /> Queue *q = create_queue();<br /> while(i < 10) {<br /> index1 = rand() % 10;<br /> index2 = rand() % 10;<br /> printf("Agregando a la fila: %s\n",cadenas[index1]);<br /> en_queue(q,cadenas[index1]);<br /> printf("Agregando a la fila: %s\n",cadenas[index2]);<br /> en_queue(q,cadenas[index2]);<br /> printf("Saliendo de la fila %s\n",de_queue(q));<br /> i++;<br /> }<br /> free_queue(q);<br />}</span> </span><br />
<br />
<br />
<span style="font-size: large;">Como es randon la salida es variada, pero podemos observar el funcionamiento:</span><br />
<span style="font-size: large;"> </span><br />
<span style="font-size: large;">Salida:</span><br />
<span style="font-size: large;"> </span><br />
<span style="font-family: "Courier New", Courier, monospace;"><span style="font-size: large;">Agregando a la fila: Cadena_5<br />Agregando a la fila: Cadena_5<br />Saliendo de la fila Cadena_5<br />Agregando a la fila: Cadena_8<br />Agregando a la fila: Cadena_2<br />Saliendo de la fila Cadena_5<br />Agregando a la fila: Cadena_5<br />Agregando a la fila: Cadena_7<br />Saliendo de la fila Cadena_8<br />Agregando a la fila: Cadena_8<br />Agregando a la fila: Cadena_7<br />Saliendo de la fila Cadena_2<br />Agregando a la fila: Cadena_9<br />Agregando a la fila: Cadena_2<br />Saliendo de la fila Cadena_5<br />Agregando a la fila: Cadena_1<br />Agregando a la fila: Cadena_3<br />Saliendo de la fila Cadena_7<br />Agregando a la fila: Cadena_8<br />Agregando a la fila: Cadena_5<br />Saliendo de la fila Cadena_8<br />Agregando a la fila: Cadena_0<br />Agregando a la fila: Cadena_3<br />Saliendo de la fila Cadena_7<br />Agregando a la fila: Cadena_4<br />Agregando a la fila: Cadena_0<br />Saliendo de la fila Cadena_9<br />Agregando a la fila: Cadena_7<br />Agregando a la fila: Cadena_1<br />Saliendo de la fila Cadena_2 </span></span><br />
<span style="font-size: large;"> </span><br />
<span style="font-size: large;">Fuente de la Imagen<br /><br /><a href="https://en.wikipedia.org/wiki/Queue_(abstract_data_type)" rel="nofollow" target="_blank">https://en.wikipedia.org/wiki/Queue_(abstract_data_type)</a> </span>albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-8013915252864094872018-11-28T15:16:00.001-08:002018-11-28T15:16:16.267-08:00C socket siempre me devuelve -1 [Winsock]<span style="font-size: large;">El problema de este post es que al momento de programar un miniservidor WEB</span><br />
<br />
<span style="font-size: large;">Este me marcaba lo siguiente:</span><br />
<br />
<span style="font-size: large;"><br /><span style="font-family: "Courier New", Courier, monospace;">Valor -1<br />socket: No error</span></span><span style="font-family: "Courier New", Courier, monospace;"><span style="font-size: large;"> </span></span><br />
<br />
<span style="font-size: large;">El codigo de prueba es:</span><br />
<br />
<span style="font-family: "Courier New", Courier, monospace;"><span style="font-size: large;">#include<winsock2.h><br />#include<stdio.h><br />#include<errno.h><br /><br />int main() {<br /> int s;<br /> if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {<br /> printf("Valor %i\n",s);<br /> perror("socket");<br /> return 1;<br /> }<br />}</span></span><br />
<br />
<span style="font-size: large;">Se compila de la siguiente manera:</span><br />
<br />
<span style="font-family: "Courier New", Courier, monospace;"><span style="font-size: large;">gcc -o test.exe test.c -lws2_32 </span></span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Al parecer los pendejos de Micro$oft siempre saliendose de lo estandar para poder utilizar socket, necesitas inicializar el Winsock de la siguiente manera.</span><br />
<br />
<span style="font-size: large;"><span style="font-family: "Courier New", Courier, monospace;">#include<winsock2.h><br />#include<stdio.h><br />#include<errno.h><br /><br />WSADATA *wsaData;<br /><br />int main() {<br /> int s,iResult;<br /> wsaData = calloc(1,sizeof(WSADATA));<br /> iResult = WSAStartup(MAKEWORD(2,2), wsaData);<br /> if (iResult != 0) {<br /> printf("WSAStartup failed: %d\n", iResult);<br /> return 1;<br /> }<br /> if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {<br /> printf("Valor %i\n",s);<br /> perror("socket");<br /> return 1;<br /> }<br />}</span> </span><br />
<br />
<span style="font-size: large;">Con lo cual el codigo ya no marca error y podremos continuar con las funciones clasicas para realizar bind, listen y connect</span><br />
<br />
<span style="font-size: large;">Posiblemente tambien se encuentre con la sorpresa de que el Socket devuelto por connect no es un FileDescriptor normal, si no uno de windows al cual no se le puede realizar fdopen y operaciones con read and write.</span><br />
<br />
<span style="font-size: large;">Saludos </span>albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-76393730064775069692018-11-24T09:53:00.000-08:002018-11-27T13:27:52.434-08:00¿Queda algo en el Buffer de Entrada stdin?<span style="font-size: large;">Muy buen dia aun que la pregunta en el titulo de este post parece una pregunta totalmente N00b. No lo es.<br /><br /><b>El objetivo de post Deja de utilizar fflush</b></span><br />
<div class="codeheader">
<span style="font-size: large;">Código</span></div>
<pre class="c geshi" style="font-family: monospace;"><ol>
<li style="font-weight: normal; vertical-align: top;"><div style="background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%; font-family: monospace; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; font-weight: normal; line-height: 1.2em; margin: 0px; padding: 0px; vertical-align: top;">
<span style="font-size: large;"><a href="http://www.opengroup.org/onlinepubs/009695399/functions/fflush.html"><span style="color: #000066;">fflush</span></a><span style="color: #009900;">(</span>stdin<span style="color: #009900;">)</span><span style="color: #339933;">;</span></span></div>
</li>
</ol>
</pre>
<span style="font-size: large;"><br />Yo
no lo utilizo, o por lo menos trato de nunca recomendarlo, solo que
ayer se lo recomendé a alguien y no me convence su implementación. <img alt=":silbar:" border="0" src="https://foro.elhacker.net/Smileys/fantasmas/silbar.gif" /><br /><br />La verdad es que quiero dar por terminado el tema de la función fflush para el Buffer de entrada. <br /><br />Todo esto en Lenguaje C <img alt=";-)" border="0" src="https://foro.elhacker.net/Smileys/fantasmas/aplaudir.gif" /><br /><br />La idea de este post viene de preguntas hechas en el foro similares a <a href="https://foro.elhacker.net/programacion_cc/iquestcomo_filtrar_todo_tipo_de_datos_de_entrada_en_un_programa-t489983.0.html">¿Como filtrar todo tipo de datos de entrada en un programa?</a><br /><br />Revisando algunas links en internet me encuentro con:<br /><a href="https://es.stackoverflow.com/questions/82431/saber-si-el-b%C3%BAfer-de-entrada-stdin-est%C3%A1-vac%C3%ADo-en-c-est%C3%A1ndar" target="_blank">https://es.stackoverflow.com/questions/82431/saber-si-el-b%C3%BAfer-de-entrada-stdin-est%C3%A1-vac%C3%ADo-en-c-est%C3%A1ndar</a><br /><a href="http://man7.org/linux/man-pages/man3/fflush.3.html" target="_blank">http://man7.org/linux/man-pages/man3/fflush.3.html</a><br /><a href="http://www.cplusplus.com/reference/cstdio/fflush/" target="_blank">http://www.cplusplus.com/reference/cstdio/fflush/</a><br /><br /><b>Sin
embargo en todos ellos hablan de que el comportamiento de fflush para
el stdin es Inesperado, por lo cual repetidamente dicen que no se debe
de usar.</b><br /><br /><b>¿Cual es la solución para limpiar el buffer de entrada, si es que realmente queda algo en el?</b><br /><br />Intente con feof, sin embargo al parecer NUNCA llega el fin del archivo para STDIN</span><br />
<div class="codeheader">
<span style="font-size: large;">Código</span></div>
<div class="codeheader">
</div>
<span style="font-size: large;"></span><br />
<span style="font-size: large;"><span style="font-family: "courier new" , "courier" , monospace;">#include<stdio.h><br />#include<string.h><br /><br />int main() {<br /> char temporal[10];<br /> printf("Ingrese menos de 10 o mas de 10 caracteres\npara ver el comportamiento de feof(stdin): ");<br /> fgets(temporal,10,stdin);<br /> temporal[strcspn(temporal,"\n\r")] = '\0';<br /> printf("Valor leido %s\n");<br /> if(feof(stdin)) {<br /> printf("stdin llego al final del archivo\n");<br /> }<br /> else {<br /> printf("stdin NO llego al final del archivo\n");<br /> } <br />}</span><br /> </span><br />
<span style="font-size: large;">El
problema de todo esto radica que cuando estamos leyendo múltiples
valores desde el teclado, aun que lo delimitemos con fgets para la
cantidad de datos que se guardaran en cada variable, el fgets , al igual
que otras funciones de entrada deja los caracteres restantes en el
buffer de entrada y son tomados automáticamente por cualquier función de
entrada de texto.<br /><br /><img alt="" border="0" src="https://i.imgur.com/iFM60zl.png" /><br /><br /><br />Como ven en la imagen, en la segunda entrada de las AAAAAAAAAAAAA, se salto el segundo "Ingrese una cadena."</span><br />
<div class="codeheader">
<span style="font-size: large;">Código:</span></div>
<div class="codeheader">
</div>
<div class="code">
<pre style="display: inline; margin-top: 0;"><span style="font-family: "courier new" , "courier" , monospace;"><span style="font-size: large;">#include<stdio.h>
#include<string.h>
int main() {
char temporal_1[10];
char temporal_2[10];
printf("Ingrese una cadena: ");
fgets(temporal_1,10,stdin);
temporal_1[strcspn(temporal_1,"\n\r")] = '\0';
printf("Ingrese una cadena: ");
fgets(temporal_2,10,stdin);
temporal_2[strcspn(temporal_2,"\n\r")] = '\0';
printf("Valor leido %s\n",temporal_1);
printf("Valor leido %s\n",temporal_2);
}</span></span></pre>
</div>
<span style="font-size: large;"><br />Este problema tambien se presenta en C++ con funciones de entrada tipo cin>><br /><br />Ejemplo:<br /><br /><img alt="" border="0" src="https://i.imgur.com/A53rMCP.png" /><br /><br />Codigo:</span><br />
<br />
<span style="font-size: large;"><span style="font-family: "courier new" , "courier" , monospace;">#include<iostream><br /><br />using namespace std;<br />int main() {<br /> int numero_1,numero_2;<br /> cout<<"Ingrese un numero: ";<br /> cin>>numero_1;<br /> cout<<"Ingrese un numero: ";<br /> cin>>numero_2;<br /> cout<<"Valor leido "<<numero_1<<endl;<br /> cout<<"Valor leido "<<numero_2<<endl;<br />}</span><br /><br /><br />Entonces pregunto:<br /><br /><b>¿Cual es la solución para limpiar el buffer de entrada, si es que realmente queda algo en el?</b><br /><b>¿Como se si es que realmente queda algo en el buffer de entrada, sin consumirlo?</b></span><br />
<br />
<span style="font-size: large;"><b>Soluciones:</b></span><br />
<br />
<span style="font-size: large;"><span style="font-family: "Courier New", Courier, monospace;">fseek(stdin, 0, SEEK_END);</span><b> </b></span><br />
<span style="font-size: large;"><b><br /></b></span>
<span style="font-size: large;"><b><br /></b></span>
<span style="font-size: large;">Esa linea de codigo nos "vacia" el buffer de entrada.</span><br />
<span style="font-size: large;"><br /><b></b></span>
<span style="font-size: large;">Otra forma de realizar esta operacion es realizando algunas validaciones en el texto leido con fgets.</span><br />
<br />
<span style="font-size: large;"> </span><span style="font-size: large;">Si bien han usado en su momento fgets, recordaran que este guarda en la
misma cadena que acaba de leer el "Enter" esto es un byte de valor 0xA
(10 en decimal)<br /><br />Esto siempre y cuando la longitud del texto leído no supere el tamaño del arreglo donde vamos a guardar nuestra cadena leida.<br /><br />Vemos un ejemplo con Codigo:</span><br />
<br />
<span style="font-size: large;"><span style="font-family: "Courier New", Courier, monospace;">#include<stdio.h><br />#include<string.h><br /><br />int main() {<br /> int len,i = 0;<br /> char temporal[10];<br /> printf("Ingrese una cadena: ");<br /> fgets(temporal,10,stdin);<br /> len = strlen(temporal);<br /> printf("Cadena Leida: %s",temporal);<br /> printf("La longitud de la cadena leida es de %i\n",len);<br /> while(i<10) printf("%.2X",temporal[i++]);<br /> printf("\n");<br />}</span></span><br />
<br />
<span style="font-family: Georgia, "Times New Roman", serif;"><span style="font-size: large;">Aqui unas cuantas salidas.<br /><br /><img alt="" border="0" src="https://i.imgur.com/QMYoyE7.png" /><br /><br />1er caso de la imagen: ingresar mas de 9 letras "A", obvio hay datos en el buffer de stdin esperando ser leeidos,<br />2do
caso de la imagen: Al ingresar exactamente 9 letras A, el ultimo byte
del buffer el byte 10 es el valor nulo '\0' En este caso queda un Enter
en el buffer de datos de stdin<br />3er caso de la imagen: Al ingresar
exactamente 8 letras A, strlen sigue considerando 9 espacios usados ya
que el Enter (0xA) esta el la posición temporal[8] y en temporal[9] esta
el byte nulo '\0'<br />4to caso de la imagen: Al ingresar exactamente 7
letras A, strlen marca una longitud de 8 espacios mismo caso que el
anterior sigue considerando el "Enter" como un valor valido de la
cadena.<br /><br />En conclusión, si al usar fgets correctamente, el valor
de nuestro arreglo en su posición strlen(temporal) - 1 es igual 0xA
entonces no queda nada en nuestro buffer de STDIN, en caso contrario si
queda Algo, ya sea solo el Enter o Texto restante + Enter.<br /><br />En
cualquier caso después de realizar esta evaluación si detectamos el caso
de que aun quede buffer pendiente por leer, podemos leerlo asi</span></span><br />
<br />
<br />
<span style="font-size: large;"><span style="font-family: "Courier New", Courier, monospace;">while ((c = getchar()) != 0xA); </span><br /><br /> </span><br />
<br />
<br />
albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-2701604639960826422018-11-21T17:01:00.001-08:002018-11-21T17:03:20.308-08:00Mini grafo con nodos aleatorios<span style="font-size: large;">#include<stdio.h><br />#include<stdlib.h><br />#include<time.h><br /><br />typedef struct str_nodo *Nodo;<br /><br />typedef struct str_nodo {<br /> int valor;<br /> Nodo *nodos; //Nodos con los que esta unido el nodo actual<br /> int n_nodos;<br />}*Grafo;<br /><br />Nodo crear_nodo(int valor);<br />void agregar_nodo(Nodo inicial,Nodo final); //Esta funcion une ambos nodos<br /><br />int main() {<br /> int i,j;<br /> Grafo grafo,temp;<br /> srand(time(NULL));<br /> grafo = crear_nodo(rand());<br /> i = 0;<br /> while(i < 1000000) {<br /> agregar_nodo(grafo,crear_nodo(rand()));<br /> i++;<br /> }<br /> <br /> i = 0;<br /> while(i < 1000) {<br /> temp = grafo->nodos[rand() % grafo->n_nodos];<br /> j = 0;<br /> while(j < 200) {<br /> agregar_nodo(temp,crear_nodo(rand()));<br /> j++;<br /> }<br /> i++;<br /> }<br /> getc(stdin);// Solo para que no se cierre el programa pero no me gusta usar getc<br /> return 0; <br />}<br /><br />Nodo crear_nodo(int valor) {<br /> Nodo nodo;<br /> nodo = calloc(1,sizeof(struct str_nodo));<br /> nodo->valor = valor;<br /> nodo->nodos = NULL;<br /> nodo->n_nodos = 0;<br /> return nodo;<br />}<br /><br />void agregar_nodo(Nodo inicial,Nodo final) {<br /> inicial->nodos = realloc(inicial->nodos,(inicial->n_nodos +1 )*sizeof(struct str_nodo*)); //Incrementamos el espacio para (inicial->n_nodos +1) Apuntadores<br /> final->nodos = realloc(final->nodos,(final->n_nodos +1 )*sizeof(struct str_nodo*)); //Incrementamos el espacio para (final->n_nodos +1) Apuntadores<br /> <br /> inicial->nodos[inicial->n_nodos] = final;<br /> final->nodos[final->n_nodos] = inicial;<br /> <br /> printf("%i <-> %i\n",inicial->valor,final->valor);<br /> inicial->n_nodos++;<br /> final->n_nodos++;<br />}</span><br />
Va una prueba con dato adjunto
<br />
<br />
Saludos
<br />
<a href="https://twitter.com/albertobsd">https://twitter.com/albertobsd</a>albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-19925274950854003412018-11-21T14:57:00.001-08:002018-11-21T14:57:49.065-08:00Plantilla de para Capturar Datos y Mostrarlos<span style="font-size: large;">Usando estructura de datos y memoria dinamica para los datos almacenados.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Descarga <a href="http://bit.ly/2FykbmA" target="_blank">plantilla_capturar_mostrar_datos.c</a></span><br />
<span style="font-size: large;"><br /></span>
<span style="font-family: "Courier New", Courier, monospace;"><span style="font-size: large;">/*<br /> Twitter: @albertobsd<br /> email: alberto.bsd@gmail.com <br /> <br /> Buscame tambien en:<br /> web: https://programaciontrabajosescolares.blogspot.com/<br /> e-mail: ProgramacionTrabajosEscolares@gmail.com<br /> facebook: https://www.facebook.com/ProgramacionTrabajosEscolares<br />*/<br /><br />#include<stdio.h> //Funciones printf, fgets<br />#include<stdlib.h> //realloc<br />#include<string.h> //strcspn<br />#include<ctype.h> //tolower<br /><br />#define MAX_LEN_ALFANUMERICA_1 100<br />#define MAX_LEN_ALFANUMERICA_2 50<br />#define MAX_LEN_ALFANUMERICA_3 20<br /><br />typedef struct plantilla_struct {<br /> char variable_alfanumerica_1[MAX_LEN_ALFANUMERICA_1];<br /> char variable_alfanumerica_2[MAX_LEN_ALFANUMERICA_2];<br /> char variable_alfanumerica_3[MAX_LEN_ALFANUMERICA_3];<br /> int variable_entera_1;<br /> int variable_entera_2;<br /> int variable_entera_3;<br /> float variable_flotante_1;<br />}TIPO;<br /><br />int funcion_ingreso_de_datos();<br />int funcion_imprimir_datos();<br /><br /><br />TIPO *tipos = NULL;<br />int contador_tipos = 0;<br /><br />int main() {<br /> int opcion;<br /> int entrar =1;<br /> char temp[10];<br /> do {<br /> printf("1) funcion_ingreso_de_datos\n");<br /> printf("2) funcion_imprimir_datos\n");<br /> printf("3) Salir\n");<br /> do{<br /> printf("Ingrese una opcion: ");<br /> fgets(temp,10,stdin);<br /> opcion = strtol(temp,NULL,10);<br /> }while(opcion <= 0); //Mientras sea menor o igual que 0<br /> <br /> switch(opcion) {<br /> case 1:<br /> printf("Usted selecciono %i\n",opcion);<br /> funcion_ingreso_de_datos();<br /> break;<br /> case 2:<br /> printf("Usted selecciono %i\n",opcion);<br /> funcion_imprimir_datos();<br /> break;<br /> case 3:<br /> printf("Usted selecciono %i\n",opcion);<br /> entrar = 0;<br /> break;<br /> default:<br /> printf("Opcion incorrecta - Mensaje de Error\n");<br /> break;<br /> }<br /> }while(entrar == 1); //Se puede dejar como "}while(entrar);"<br /> return 0; <br />}<br /><br />int funcion_ingreso_de_datos() {<br /> int opcion;<br /> int entrar =1,entrar_opcion_si_no;<br /> char temp[10];<br /> do {<br /> <br /> tipos = realloc(tipos,(contador_tipos+1)*sizeof(struct plantilla_struct)); //Incrementamos el espacio para 1 Variable TIPO mas en el arreglo<br /> <br /> //Capturamos variable_alfanumerica_1<br /> printf("Capture variable_alfanumerica_1: ");<br /> fgets(tipos[contador_tipos].variable_alfanumerica_1,MAX_LEN_ALFANUMERICA_1,stdin);<br /> tipos[contador_tipos].variable_alfanumerica_1[strcspn(tipos[contador_tipos].variable_alfanumerica_1,"\n\r")] = '\0'; //Reemplazamos los retornos de linea con caracrer nulo, terminador de cadena<br /> <br /> //Capturamos variable_alfanumerica_2<br /> printf("Capture variable_alfanumerica_2: ");<br /> fgets(tipos[contador_tipos].variable_alfanumerica_2,MAX_LEN_ALFANUMERICA_2,stdin);<br /> tipos[contador_tipos].variable_alfanumerica_2[strcspn(tipos[contador_tipos].variable_alfanumerica_2,"\n\r")] = '\0'; //Reemplazamos los retornos de linea con caracrer nulo, terminador de cadena<br /> <br /> //Capturamos variable_alfanumerica_3<br /> printf("Capture variable_alfanumerica_3: ");<br /> fgets(tipos[contador_tipos].variable_alfanumerica_3,MAX_LEN_ALFANUMERICA_3,stdin);<br /> tipos[contador_tipos].variable_alfanumerica_3[strcspn(tipos[contador_tipos].variable_alfanumerica_3,"\n\r")] = '\0'; //Reemplazamos los retornos de linea con caracrer nulo, terminador de cadena<br /> <br /><br /> //Capturamos variable_entera_1<br /> do {<br /> printf("Capture variable_entera_1: (Solo mayores que 0) ");<br /> fgets(temp,10,stdin);<br /> tipos[contador_tipos].variable_entera_1 = strtol(temp,NULL,10); //Solo procesamos numeros BASE 10<br /> <br /> }while(tipos[contador_tipos].variable_entera_1 <= 0); // Salimos del DO solo si el valore leido es mayor o igual a 1<br /><br /> //Capturamos variable_entera_2<br /> do {<br /> printf("Capture variable_entera_2: (Solo mayores o iguales que 0) ");<br /> fgets(temp,10,stdin);<br /> tipos[contador_tipos].variable_entera_2 = strtol(temp,NULL,10); //Solo procesamos numeros BASE 10 <br /> }while(tipos[contador_tipos].variable_entera_2 < 0); // Salimos del DO solo si el valore leido es mayor o igual a 0<br /> <br /><br /> //Capturamos variable_entera_3<br /> do {<br /> printf("Capture variable_entera_3: (Solo Negativos) ");<br /> fgets(temp,10,stdin);<br /> tipos[contador_tipos].variable_entera_3 = strtol(temp,NULL,10); //Solo procesamos numeros BASE 10 <br /> }while(tipos[contador_tipos].variable_entera_3 >= 0); // Salimos del DO solo si el valor leido es negativo<br /> <br /> //Capturamos variable_flotante_1<br /> do {<br /> printf("Capture variable_flotante_1: (Solo distintos que 0) ");<br /> fgets(temp,10,stdin);<br /> tipos[contador_tipos].variable_flotante_1 = strtof(temp,NULL);<br /> }while(tipos[contador_tipos].variable_flotante_1 == 0.0); // Salimos del DO solo si el valor leido distinto de 0<br /> <br /> entrar_opcion_si_no = 1;<br /> do{<br /> printf("Desea segir ingresando mas datos? (s/n)\n");<br /> fgets(temp,10,stdin);<br /> switch(tolower(temp[0])) {<br /> case 's':<br /> entrar_opcion_si_no = 0;<br /> printf("Selecciono SI\n");<br /> break;<br /> case 'n':<br /> entrar_opcion_si_no = 0;<br /> printf("Selecciono NO\n");<br /> entrar = 0; // Se cambia la variable para salir del menu principal<br /> break;<br /> default:<br /> printf("opcion incorrecta, solo 's' o 'n'\n");<br /> break;<br /> }<br /> opcion = strtol(temp,NULL,10);<br /> }while(entrar_opcion_si_no == 1);<br /> <br /> contador_tipos++; //Aqui incrementamos el contador_tipos que indica cuantos valores completos tenemos de la estructura plantilla_struct<br /> }while(entrar == 1); //Se puede dejar como "}while(entrar);"<br />}<br /><br />int funcion_imprimir_datos() { //Imprimir los datos no tiene mucho sentido, solo hay que recorrer correctamente la cantidad de registros previamente capturados<br /> int i = 0;<br /> while(i < contador_tipos) {<br /> printf("Datos del registro %i\n",(i+1));<br /> printf("variable_alfanumerica_1: %s\n",tipos[i].variable_alfanumerica_1);<br /> printf("variable_alfanumerica_2: %s\n",tipos[i].variable_alfanumerica_2);<br /> printf("variable_alfanumerica_3: %s\n",tipos[i].variable_alfanumerica_3);<br /> printf("variable_entera_1: %i\n",tipos[i].variable_entera_1);<br /> printf("variable_entera_2: %i\n",tipos[i].variable_entera_2);<br /> printf("variable_entera_3: %i\n",tipos[i].variable_entera_3);<br /> printf("variable_flotante_1: %f\n",tipos[i].variable_flotante_1);<br /> printf("\n");//Enter adicional<br /> i++;<br /> }<br />}</span></span>albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-3888454843975398472018-11-20T14:38:00.000-08:002018-11-20T16:37:37.188-08:00¿He liberado todos los apuntadores?<span style="font-size: large;">Para aquellos que les guste programar con memoria dinamica en C,
frecuentemente se encontraran en ocasiones tener la sensacion de no
haber liberado un apuntador, esto puede ser cuando tambien trabajamos
con arreglos (longitud variable) de apuntadores.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Para facilitar
esta tarea se pueden programa sus propias implementaciones que lleven un
conteo de cuantos apuntadores se han creado y de cuantos se han
liberado.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Si al final del programa el resultado es 0, entonces pueden estar tranquilos de que todo se libero correctamente.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Esta
sencilla implementacion, solo lleva dicho conteo, NO lleva conteo de
memoria utilizada y/o control de cuales apuntadores ya fueron liberados,
eso ya es harina de otro costal.</span><br />
<span style="font-size: large;"></span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Codigo:</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;"><span style="font-family: "courier new" , "courier" , monospace;">#include<stdlib.h><br /><br />unsigned int N_ptr = 0;<br /><br />unsigned int test_result() {<br /> return N_ptr;<br />}<br /><br />void *test_realloc(void *ptr,size_t size) {<br /> void *ptr_new = NULL;<br /> ptr_new = realloc(ptr,size);<br /> if(ptr == NULL && ptr_new != NULL){<br /> N_ptr++;<br /> }<br /> return ptr_new;<br />}<br /><br />void *test_calloc(size_t nmemb,size_t size) {<br /> void *ptr = NULL;<br /> ptr = calloc(nmemb,size);<br /> if(ptr != NULL) {<br /> N_ptr++;<br /> }<br /> return ptr; <br />}<br /><br />void *test_malloc(size_t size) {<br /> void *ptr = NULL;<br /> ptr = malloc(size);<br /> if(ptr != NULL) {<br /> N_ptr++;<br /> }<br /> return ptr; <br />}<br /><br />int test_free(void *ptr) {<br /> N_ptr--;<br /> free(ptr);<br />}</span></span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Se
podrian sustituir las funciones malloc, calloc, realloc y free en
nuestro programa hacia estas funciones para testear y exclusivamente
para prueba. posteriormente volver a dejarlas llamadas originales.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Al final del main despues de liberar todo podremos colocar esta linea</span><br />
<span style="font-size: large;"><br /></span>
<br />
<div class="codeheader">
<br />
<span style="font-size: large;">Código:</span></div>
<div class="code">
<pre style="display: inline; margin-top: 0;"><span style="font-size: large;"> </span></pre>
</div>
<div class="code">
<pre style="display: inline; margin-top: 0;"><span style="font-size: large;">printf("Valor %i",test_result());</span></pre>
</div>
<br />
<span style="font-size: large;">Si en nuestra salida del progrma el resultado es 0, significa que todo esta bien.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">En
caso contrareo, deberemos depurar en nuestras subfunciones el antes y
el despues de cada llamada para validar en que función esta el problema.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Saludos</span>albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-18097599633768676942018-11-07T10:33:00.001-08:002018-11-07T10:33:35.466-08:00Efectos retro con Canvas HTML5<div class="separator" style="clear: both; text-align: left;">
<span style="font-size: large;">Personalmente si hago algo me gusta automatizarlo y hacerlo desde 0, actualmente estoy haciendo algunos videos, y para ello planeo utilizar efectos retro. Muchos de los cuales puedo realizar y animar mediante el eso de un Canvas de HTML5.</span></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-_mWUF6xZnew/W-MtxB5ZZYI/AAAAAAAAYDE/5lpVeuqW7EIR-EBmfIBS2RnjOHwLBFcaQCLcBGAs/s1600/tv_bars.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="716" data-original-width="1274" height="358" src="https://3.bp.blogspot.com/-_mWUF6xZnew/W-MtxB5ZZYI/AAAAAAAAYDE/5lpVeuqW7EIR-EBmfIBS2RnjOHwLBFcaQCLcBGAs/s640/tv_bars.png" style="border: 1px solid #000000;" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><h1 class="firstHeading" id="firstHeading" lang="en">
SMPTE color bars</h1>
</td></tr>
</tbody></table>
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://4.bp.blogspot.com/--8UVGlbzlHo/W-MuHP0z9nI/AAAAAAAAYDM/MX5avLmkSVYdXGyVu_JEkmY5CvA72B1kQCLcBGAs/s1600/estatica.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="716" data-original-width="1274" height="358" src="https://4.bp.blogspot.com/--8UVGlbzlHo/W-MuHP0z9nI/AAAAAAAAYDM/MX5avLmkSVYdXGyVu_JEkmY5CvA72B1kQCLcBGAs/s640/estatica.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: large;"><b>Distorsión de televisión</b></span></td></tr>
</tbody></table>
<br />albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-79042157383723687912018-10-17T17:06:00.001-07:002018-10-17T17:06:35.026-07:00Menu con do-while y switch en C<span style="font-size: large;">Plantilla de menu basico, mediante do-while y un switch.</span><br />
<br />
<span style="font-size: large;">Video en Youtube</span><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/V_QYMKENFLU/0.jpg" src="https://www.youtube.com/embed/V_QYMKENFLU?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<span id="goog_1448646932"></span><span id="goog_1448646933"></span><br />
<br />
<span style="font-size: large;">Funcionando</span><br />
<br />
<img alt="" height="400" src="data:image/png;base64,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" width="325" /><br />
<br />
<span style="font-size: large;">Parte relevante del codigo</span><br />
<br />
<img alt="" height="294" src="data:image/png;base64,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" width="400" /><br />
<br />
<span style="font-size: large;">Descargar codigo desde aqui: <a href="https://mega.nz/#!bHZgTQYK!a8yMmyv_vmWlkRd3CEb4E533ZSHlxUYeqevyyBNFyGQ" rel="nofollow" target="_blank">menu.c</a></span> albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-42836962578432675012017-09-11T08:38:00.000-07:002017-09-11T08:38:06.965-07:00Recomendacion para Disco Duro Cifrado en FreeBSD<span style="font-family: Verdana, arial, helvetica, serif; font-size: 12pt; line-height: 1.3em;">Si estamos usando FreeBSD y queremos cifrar todo nuestro disco duro no duden en preguntar sus dudas.<br /><br />El comando geli para inicializar la criptografia en nuestro disco duro es el siguiente:</span><br />
<div class="codeheader" style="font-family: Verdana, arial, helvetica, serif; font-size: 11px;">
Code:</div>
<div class="code" style="background-color: #eaeced; font-family: "Courier New", Verdana, Arial, helvetica, serif;">
geli init -a hmac/sha256 -b -e AES-XTS -l 256 -s 4096 -i 524288 -B /tmp/USBTEMP/backup_metadata.eli -K /tmp/USBTEMP/da1p1.key da1p1</div>
<span style="font-family: Verdana, arial, helvetica, serif; font-size: 12pt; line-height: 1.3em;"><br />Obviamente hablamos de una instalacion nueva. No se puede en una instalacion preexistente, a no ser que vallamos a mover toda nuestra informaacion de un disco duro sin cifrar a algun disco duro cifrado.<br /><br />Previamente necesitamos crear un archivo "llave" de manera aleatoria con DD</span><br />
<div class="codeheader" style="font-family: Verdana, arial, helvetica, serif; font-size: 11px;">
Code:</div>
<div class="code" style="background-color: #eaeced; font-family: "Courier New", Verdana, Arial, helvetica, serif;">
dd if=/dev/random of=/tmp/USBTEMP/da1p1.key bs=4096 iseek=128 count=32</div>
<span style="font-family: Verdana, arial, helvetica, serif; font-size: 12pt; line-height: 1.3em;"><br />Esto nos genera un archivo de 128 Kilobytes (bs=4096 * count=32) de informacion aleatoria, pasandole este archivo a geli, necesitaremos este archivo cada vez que iniciemos nuestro ordenador, y mas nos vale tener al menos otras 3 copias de seguridad de dicho archivo.<br /><br />Sumado al archivo en la memoria USB para poder cargar nuestro sistema tendremos:</span><br />
<ul style="font-family: Verdana, arial, helvetica, serif; font-size: 11px; margin-bottom: 0px; margin-top: 0px;">
<li><span style="font-size: 12pt; line-height: 1.3em;">Disco Duro cirado con AES-XTS y una clave de 256 bits</span></li>
<li><span style="font-size: 12pt; line-height: 1.3em;">Autenticacion de sectores del disco usando hmac/sha256</span></li>
<li><span style="font-size: 12pt; line-height: 1.3em;">La Autenticacion con hmac/sha256 Envita que nos ataquen usando Replay</span></li>
<li><span style="font-size: 12pt; line-height: 1.3em;">Peticion de passphrase Antes de montar el Disco Duro principal</span></li>
<li><span style="font-size: 12pt; line-height: 1.3em;">El passphare es juntado con el salt y nuestro archivo de 128 Kilobytes y derivado 524288 veces para poder descifrar la clave maestra previamente cifrada y guardada en la metadata</span></li>
</ul>
<br style="font-family: Verdana, arial, helvetica, serif; font-size: 11px;" /><span style="font-family: Verdana, arial, helvetica, serif; font-size: 12pt; line-height: 1.3em;">La unica desventaja que le veo a esta implementacion es:</span><br style="font-family: Verdana, arial, helvetica, serif; font-size: 11px;" /><br />
<ul style="font-family: Verdana, arial, helvetica, serif; font-size: 11px; margin-bottom: 0px; margin-top: 0px;">
<li><span style="font-size: 12pt; line-height: 1.3em;">Disminucion del Performance al momento de Leer/Escribir informacion en el disco ya que todo es cifrado.</span></li>
<li><span style="font-size: 12pt; line-height: 1.3em;">Lo anterior pordria ser mitigado Teniendo algun Hardware acelarador para operaciones criptograficas y un Disco Duro de Estado solido.</span></li>
<li><span style="font-size: 12pt; line-height: 1.3em;">Disminucion de Capacidad de almacenamiento, Dado que estamos usando un sistema de Autenticacion, este necesita guardar los checksum de cada sector de disco para determinar que no han sido modificados por terceros</span></li>
<li><span style="font-size: 12pt; line-height: 1.3em;">Ejemplo de lo Anterior un Disco Duro de 22 Gigabytes termina con capacidad de 19 GB. Pierde al rededor de 14% de Almacenamiento dedicado para la Autenticacion de la información</span></li>
</ul>
<br style="font-family: Verdana, arial, helvetica, serif; font-size: 11px;" /><span style="font-family: Verdana, arial, helvetica, serif; font-size: 12pt; line-height: 1.3em;">Saludos!</span>albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-86585607684715432582017-09-07T21:36:00.002-07:002017-09-07T21:36:58.196-07:00Extraer informacion de Cifrado en DiscoDuro de FreeBSD<div>
<span style="font-size: large;">FreeBSD ofrece la opcion de cifrar completamente el disco duro. La principal herramienta es Geli[2].</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Para ver la información sobre el cifrado del disco, OJO no la información cifrada, sino la información relacionada con el tipo y modo de cifrado usado para el disco duro en cuestion, es necesario primero obtener acceso fisco al disco, una en otra instalación con FreeBSD podemos extraer el sector que tiene la meta-data a analizar, este sector del disco duro (512 Bytes) se encuentra en el ultimo sector de la particion cifrada.</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Si no sabemos cual particion es la particion cifrada podemos extraer el ultimo sector de todas la particiones de el disco duro.</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Ejemplo:</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Discoduro a analizar /dev/da1</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Si listamos /dev/da1* podremos ver que tiene 2 particiones para este caso en particular</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;"># ls /dev/da1*</span></div>
<div>
<span style="font-size: large;">/dev/da1p1</span></div>
<div>
<span style="font-size: large;">/dev/da1p2</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Para extraer la informacion tenemos que usar el comando dd.</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Tambien necesitamos saber cuanto espacio tiene el disco duro</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;"># geom disk list</span></div>
<div>
<span style="font-size: large;">o</span></div>
<div>
<span style="font-size: large;"># gpart list</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Ejemplo de salida:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;">Providers:</span></div>
<div>
<span style="font-size: large;"><span style="font-family: "courier new" , "courier" , monospace;">1. Name: </span><span style="font-family: "courier new" , "courier" , monospace;">da1p1</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> <b>Mediasize: 20401094656 (19G)</b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> <b>Sectorsize: 512</b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> Stripesize: 0</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> Stripeoffset: 32768</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> Mode: r1w1e1</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> rawtype: 7</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> length: 20401094656</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> offset: 0</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> type: freebsd-ufs</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> index: 1</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> <b>end: 39845887</b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> <b>start: 0</b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;">2. Name: da1p2</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> Mediasize: 1073708032 (1.0G)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> Sectorsize: 512</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> Stripesize: 0</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> Stripeoffset: 3221258240</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> Mode: r1w1e0</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> rawtype: 1</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> length: 1073708032</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> offset: 20401094656</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> type: freebsd-swap</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> index: 2</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> end: 41942973</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: large;"> start: 39845888</span></div>
</div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Para este ejemplo la particion tiene 20401094656 con lo cual si dividimos entre 512 nos da un total 39845888 Sectores con lo cual el ultimo sector valido es 39845887 que el que tenemos que leer, entonces el comando para extraer dicho sector es:</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;"># dd if=/dev/da1p1 of=./sector.backup bs=512 iseek=39845887 count=1</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Si nuestros calculos fueron acertados tendremos un archivo llamado sector.backup de 512 bytes.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">El contenido de ese archivo puede variar mucho dependiendo del estado previo del disco duro.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Si el disco duro esta cifrado con mediante geli el archivo empezara con la siguiente leyenda:</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">GEOM::ELI, lo restante es informacion en binario con el siguiente orden</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: large;">struct g_eli_metadata {</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>char<span style="white-space: pre;"> </span>md_magic[16];<span style="white-space: pre;"> </span>/* Magic value. */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>uint32_t<span style="white-space: pre;"> </span>md_version;<span style="white-space: pre;"> </span>/* Version number. */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>uint32_t<span style="white-space: pre;"> </span>md_flags;<span style="white-space: pre;"> </span>/* Additional flags. */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>uint16_t<span style="white-space: pre;"> </span>md_ealgo;<span style="white-space: pre;"> </span>/* Encryption algorithm. */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>uint16_t<span style="white-space: pre;"> </span>md_keylen;<span style="white-space: pre;"> </span>/* Key length. */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>uint16_t<span style="white-space: pre;"> </span>md_aalgo;<span style="white-space: pre;"> </span>/* Authentication algorithm. */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>uint64_t<span style="white-space: pre;"> </span>md_provsize;<span style="white-space: pre;"> </span>/* Provider's size. */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>uint32_t<span style="white-space: pre;"> </span>md_sectorsize;<span style="white-space: pre;"> </span>/* Sector size. */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>uint8_t<span style="white-space: pre;"> </span>md_keys;<span style="white-space: pre;"> </span>/* Available keys. */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>int32_t<span style="white-space: pre;"> </span>md_iterations;<span style="white-space: pre;"> </span>/* Number of iterations for PKCS#5v2. */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>uint8_t<span style="white-space: pre;"> </span>md_salt[G_ELI_SALTLEN]; /* Salt. */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>/* Encrypted master key (IV-key, Data-key, HMAC). */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>uint8_t<span style="white-space: pre;"> </span>md_mkeys[G_ELI_MAXMKEYS * G_ELI_MKEYLEN];</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><span style="white-space: pre;"> </span>u_char<span style="white-space: pre;"> </span>md_hash[16];<span style="white-space: pre;"> </span>/* MD5 hash. */</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"></span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">} __packed;</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Me tome la molestia de Generar una herramienta en C que lee la informacion y le pasa las funciones existentes en el codigo fuente de geli para organizar el buffer acorde al formato de la estructura.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">El programa puede ser visto en mi cuenta de github[3] si lo compilamos y ejecutamos pasandole como parametro el archivo de 512 bytes tendremos una salida similar a la siguiente [Algunos datos fuero cambiados]:</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: large;">albertobsd@XHGC-VMBox:~ % ./eli_metadata sector.backup</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">Magic: GEOM::ELI</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">Version: 7</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">Flags: 2</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">E ALGO: 22</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">Key Length: 128</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">A Algo: 0</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">P Size: 23622320128</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">Sector Size: 4096</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">Avaible Keys: 1</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">Iterations: 218830</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">Salt: E8CF4BB53DA62DC60B8CAD36119D62B806D95524828286533728C4045E319DBBA1486522EA0454887E1094AD3FAFA0295E9350F1259AAC4B791D42A02F3A6BF2</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">Master Key: 3F4E170DAFF6539E9301EEF2840ED233BA3B84D02EB96</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">3AEBB0CA1EED891034A85A3BB325F7B09398706944DFE84CE4748D2C4F0E1FEA4FD601CC18A922ADE51C9D7DC740292A979153B744FC49F47956E24E23D64BFF854F04E3AD41C39215D834DF5E317FF9C1661D9B3300E40D85CE4C270BF57DD1AA82489A97F6741A119AF25D1987ED584E1585FD7ADAE7406D9119AC7AEE654DA2B9C28D2D39599593E1B751BAE614C921E814660E240D18B7650477E935941299F7D34C91350BD289902B7F7DF23D7523C1B6FC0AB33CAB3AF07E5EA0E97835EF13F31B1F56004A552F074951D8B490FEA605D449E2AEA774574BDFEE9153392E4084DF934FCA40638B676A868E3BAB8CA0E0A1912B348C645F74BCA3AB7D697053DD25107981086284F687D1D5EF1DA16280EE7CD0920A92CDAFAF7970D084C4C344FAB3117D0993A591AA43B1D09BE6D5AFB12C82C375BD980AC60F7E0A65C146F8E54E1D84FA0D73933EC26341E5B1D11BA14AF8FA3990F834C4FA39BEF17EECCE206670E5E854B</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"></span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">MD5: BD5DA8BAE0C0C6AAC7503769A3CE9110</span><br />
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Datos interesantes de la salida:</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-family: "Courier New", Courier, monospace; font-size: large;">E ALGO: 22</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Podemos ver en</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: large;">/usr/src/sys/opencrypto/cryptodev.h</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: large;">#define<span style="white-space: pre;"> </span>CRYPTO_AES_XTS<span style="white-space: pre;"> </span>22</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Que esta cifrado usando AES_XTS que segun [4] es el estandar recomenado para el cifrado de disco.</span></div>
</div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: large;">Key Length: 128</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">El cifrado usa una Llave de 128 bits, se podria configurar a 256 para un mejor cifrado.</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: large;">A Algo: 0</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><br /></span>
<span style="font-size: large;">El sistema no tiene Autenticacion, esto quiere decir que no se tiene forma de saber si la informacion que leemos del disco a sido modificada o sobreescirta por terceros, esto tambien da lugar a un ataque tipo replay para poder calcular la clave maestra</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><br /></span>
<span style="font-family: "Courier New", Courier, monospace; font-size: large;">Avaible Keys: 1</span><br />
<span style="font-family: "Courier New", Courier, monospace; font-size: large;"><br /></span>
<span style="font-size: large;">El sistema solo tiene una llave maestra lo cual si se nos olvida nuestra "passphrase" o se nos pierden nuestras llaves tendremos muy pocas (NULAS) posibilidades de recuperar nuestra informacion</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: large;">Iterations: 218830</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Nuestra "passphrase" junto con el Salt y nuestros Keyfiles si existen es derivada 218830 veces mediante </span><span style="font-size: large;">pkcs5v2_genkey en g_eli.c y el resultado de esta operacion se usa para desencriptar la llave encripada en.</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace; font-size: large;">Master Key: 3F4E170DAFF6539E9301EEF2840ED233BA3B84D02EB96</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;">3AEBB0CA1EED891034A85A3BB325F7B09398706944DFE84CE4748D2C4F0E1FEA4FD601CC18A922ADE51C9D7DC740292A979153B744FC49F47956E24E23D64BFF854F04E3AD41C39215D834DF5E317FF9C1661D9B3300E40D85CE4C270BF57DD1AA82489A97F6741A119AF25D1987ED584E1585FD7ADAE7406D9119AC7AEE654DA2B9C28D2D39599593E1B751BAE614C921E814660E240D18B7650477E935941299F7D34C91350BD289902B7F7DF23D7523C1B6FC0AB33CAB3AF07E5EA0E97835EF13F31B1F56004A552F074951D8B490FEA605D449E2AEA774574BDFEE9153392E4084DF934FCA40638B676A868E3BAB8CA0E0A1912B348C645F74BCA3AB7D697053DD25107981086284F687D1D5EF1DA16280EE7CD0920A92CDAFAF7970D084C4C344FAB3117D0993A591AA43B1D09BE6D5AFB12C82C375BD980AC60F7E0A65C146F8E54E1D84FA0D73933EC26341E5B1D11BA14AF8FA3990F834C4FA39BEF17EECCE206670E5E854B</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: large;"></span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">El archivo termina con un MD5 Checksum de los valores en binario previamente mostrados, solo para validar que la información sea correcta.</span></div>
<div>
<span style="font-size: large;"><br /></span></div>
<div>
<span style="font-size: large;">Si es posible usar la información contenida en el archivo para Atacar por fuerza bruta y obtener la Clave Maestra decifrada pero en computacionalmente casi imposible de realizar.</span></div>
<div>
<span style="font-size: large;"><br /></span>
<br /></div>
<span style="font-size: large;">[2] Man page of Eli<a href="https://www.freebsd.org/cgi/man.cgi?query=geli&apropos=0&sektion=8&manpath=FreeBSD+11.1-RELEASE&arch=default&format=html">https://www.freebsd.org/cgi/man.cgi?query=geli&apropos=0&sektion=8&manpath=FreeBSD+11.1-RELEASE&arch=default&format=html</a></span><br />
<span style="font-size: large;">[3] Herramienta Utilizada: <a href="https://github.com/albertobsd/geli_metadata">https://github.com/albertobsd/geli_metadata</a></span><br />
<span style="font-size: large;">[4] <a href="https://en.wikipedia.org/wiki/Disk_encryption_theory">https://en.wikipedia.org/wiki/Disk_encryption_theory</a></span><br />
<br />albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-31555095471768512562017-09-05T07:34:00.000-07:002017-09-05T07:34:48.773-07:00Borrar Disco Duro Usando dd<span style="font-size: large;">Comando:</span><br />
<span style="font-size: large;"><br /></span>
<span style="background-color: #666666; font-size: large;"><span style="color: white; font-family: Courier New, Courier, monospace;">dd if=/dev/zero of=/dev/sdN1 bs=10M</span></span><br />
<span style="font-size: large;"><br /></span>
<b style="font-size: x-large;">Atencion! </b><span style="font-size: large;"><u>Podrían borrar su sistema y perder su información si se equivocan el la eleccion del parametro of (Output file).</u></span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">of=/dev/sdN1 es el disco que queremos sobrescribir y deberían tener noción cual es el disco que planean sobrescribir.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Aun que no sea nada nuevo es posible sobrescribir toda la información que contiene un Disco Duro usando la herramienta de Bodigo Abierto llamada dd <a href="https://en.wikipedia.org/wiki/Dd_(Unix)">[1]</a>.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Esto es útil cuando queremos vender o regalar un disco duro que a a estado con nosotros por algún tiempo, y ademas de ser útil debería de ser Regla Borrar el disco duro de forma completa y segura para que la información que esta o estuvo contenida en el sea Totalmente Irrecuperable.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">He estado haciendo unas pruebas y he borrado/limpiado mis discos duros para poder venderlos.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Es necesario comentar que <b><u>este proceso es muy lento</u></b> y puede variar de una computadora a otra dependiendo de la tecnología del disco duro usado y el hardware con el que contemos en este momento.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">El sistema que use es FreeBSD 11.1 Release</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">La forma rapida de borrado completo y seguro de un disco duro de 500 GB Puede tardar hasta 4 Horas. A una velocidad de 35 MBps toma aproximadamente 2</span><span style="font-size: large;">44 Minutos escribir todo el disco duro con ceros (Cada byte escrito con un valor 0).</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Comando:</span><br />
<span style="font-size: large;"><br /></span>
<span style="background-color: #666666; font-size: large;"><span style="color: white; font-family: Courier New, Courier, monospace;">dd if=/dev/zero of=/dev/dN bs=10M</span></span><br />
<div>
<span style="background-color: #666666; font-size: large;"><span style="color: white; font-family: Courier New, Courier, monospace;"><br /></span></span></div>
<span style="font-size: large;">La forma Lenta de borrado completo y seguro de un disco duro de 500 GB puede tardar hasta 11 Horas. Esto seria a una velocidad de 16 MBps y toma al rededor de 640 Minutos.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Comando:</span><br />
<span style="font-size: large;"><br /></span>
<span style="background-color: #666666; color: white; font-family: "Courier New", Courier, monospace; font-size: large;">dd if=/dev/random of=/dev/dN bs=1M</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">La diferencia entre esta forma y la anterior radica en que ahora tomamos bytes Pseudo-Aleatorios para sobrescribir el Disco Duro y la generación de bytes Pseudo-Aleatorios toma algo de tiempo dependiendo del algoritmo usado por nuestro sistema Operativo.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Los usuarios de Linux tienen que usar el device /dev/urandom ya que el sistema de Linux maneja de forma diferente el dispositivo /dev/random y se bloquea mas seguido haciéndolo muy lento aun.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">Comando:</span><br />
<span style="font-size: large;"><br /></span>
<span style="background-color: #666666; color: white; font-family: "Courier New", Courier, monospace; font-size: large;">dd if=/dev/urandom of=/dev/dN bs=1M</span><br />
<div>
<span style="background-color: #666666; color: white; font-family: "Courier New", Courier, monospace; font-size: large;"><br /></span></div>
<span style="font-size: large;">El Modo Paranoico de Borrado de Disco Duro consiste en repetir hasta 7 veces el proceso descrito en el modo Lento y llevaria 7 veces mas tiempo hacerlo.</span><br />
<span style="font-size: large;"><br /></span>
<br />
<span style="font-size: large;">Saludos!</span><br />
<br />
<span style="font-size: large;">Referencias.</span><br />
<span style="font-size: large;"><br /></span>
<span style="font-size: large;">[1] <a href="https://en.wikipedia.org/wiki/Dd_(Unix)">https://en.wikipedia.org/wiki/Dd_(Unix)</a></span><br />
<span style="font-size: large;">[2] <a href="https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4">https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4</a></span><span id="goog_268516134"></span><a href="https://www.blogger.com/"></a><span id="goog_268516135"></span><br />
<br />
<br />albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-50222213188492677812017-07-15T08:35:00.001-07:002017-07-15T08:38:46.965-07:00Cable modem Ubee - WPA2 y WPS por defecto<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-eHJJbZCLsAc/WWo28GdapMI/AAAAAAAAW9I/O6E8J6zsuZYbKJrvDKke6d6CMDLkglFcwCLcBGAs/s1600/ubee_header.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="112" data-original-width="1024" height="70" src="https://3.bp.blogspot.com/-eHJJbZCLsAc/WWo28GdapMI/AAAAAAAAW9I/O6E8J6zsuZYbKJrvDKke6d6CMDLkglFcwCLcBGAs/s640/ubee_header.jpg" width="640" /></a></div>
<br />
<br />
Bueno recientemente me instalaron el internet de Megacable y me entregaron un modem algo desconocido, pero realmente desconozco que tan usado sea esta marca de modems en las tecnologias de cable coaxial.<br />
<br />
Me instalaron un cable modem Ubee Modelo 1307<br />
<br />
<b>Desconosco si estas condifuraciones sean para todos lo modelos he incluso para este mismo modelo en otra Compañia de cable.</b><br />
<br />
La cable WPA/WPA2 por defecto para el equipo que me entregaron es PARTE de la MAC Address ORIGINAL. En especifico los ultimos 5 Octetos<br />
<br />
Resalto "parte" y "original" ya que si escaneamos las redes Wireless la MAC address Wireless cambia en el ultimo octeto.<br />
<br />
<h4>
Ejemplo ficticio</h4>
MAC Adress Original: F8:DA:0C:00:00:00 (Esta es la que viene en nuestra etiqueta)<br />
MAC Adress WAN: F8:DA:0C:00:00:01 (Esta es la que reconoce la compañia de cable)<br />
MAC Adress MTA: F8:DA:0C:00:00:02 (NPI)<br />
MAC Adress Ethernet: F8:DA:0C:00:00:03 (Mac address que ven las computadoras conectas por cable)<br />
MAC Adress Wireless: F8:DA:0C:00:00:04 (Mac addres que ven los equipos wireless)<br />
<br />
Entonces para este caso ficticio la cable WPA es DA0C000000<br />
Y el SSID de la red Inalambrica es: Ubee0000<br />
<br />
Los datos reales pueden cabiar.<br />
<br />
Entonces si tenemos acceso a la MAC address inalambrica la clave serian los 4 octetos de en medio mas los 2 ultimos digitos del SSID.<br />
<br />
Otro ejemplo<br />
<br />
MAC Adress Wireless: F8:DA:0C:10:10:04<br />
SSID: Ubee1000<br />
<br />
La cable WPA seria los numeros resaltados a continuacion:<br />
MAC Adress Wireless: F8:<b>DA:0C:10:10</b>:04<br />
SSID: Ubee10<b>00</b><br />
<b><br /></b>
Por lo que para este ejemplo seria <b>DA0C101000</b><br />
<div>
<br /></div>
Ademas de todo esto el PIN WPS por default que venia en mi dispositivo es <b>12345670</b><br />
<br />
<h3>
Interfaz Web</h3>
<br />
La direccion para accesar a la interfaz web es <a href="http://192.168.0.1/">http://192.168.0.1</a><br />
<br />
El usurio y clave para entrar es user, user esto es:<br />
usuario: user<br />
contraseña: user<br />
<br />
<h3>
<b>Recomendaciones</b></h3>
Desactivar el WPS<br />
Cambiar el nombre de la red inalambrica<br />
Cambiar la clave por defecto.<br />
<br />
<br />
Saludos!albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-28903074590246862022016-11-02T12:12:00.003-07:002016-11-02T12:12:25.706-07:00Hosting de ImagenesBueno si no es mucho decir acabo de terminar la fase beta para un hosting de Imágenes al estilo imgur + 9gag.<br />
<br />
Cualquier puede subir sus imágenes.en:<br />
<br />
<div style="text-align: center;">
<a href="http://imgs.mx/"><span style="font-size: large;">http://imgs.mx/</span></a></div>
<br />
Próximamente agregare Estadísticas para sus archivos.<br />
<br />
Saludos!albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-12724372762062844242016-10-21T11:25:00.000-07:002016-10-21T11:25:04.267-07:00Blackout de DNSPrimero no cargaba github, al cual llegue por una busqueda en google. sobre un error del DNS de la api de twitter usando Codebird en PHP, despues de reinicar la maquina, la pagina de github seguia igual y para mi sorpresa tambien la de Twitter, el app del celular funcionaba esporadicamente, no se por que.<br />
<br />
la pagina web de whatsapp estaba igual y al parecer varios otros servcios como reddit entre otros.<br />
<br />
La respuesta era la misma desde el nslookup todos dan timeout usando el servidor DNS de Google:<br />
<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><b>> github.com</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>Servidor: google-public-dns-a.google.com</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>Address: 8.8.8.8</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b><br /></b></span>
<span style="font-family: Courier New, Courier, monospace;"><b>DNS request timed out.</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> timeout was 2 seconds.</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>DNS request timed out.</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> timeout was 2 seconds.</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>DNS request timed out.</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> timeout was 2 seconds.</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>*** google-public-dns-a.google.com no encuentra github.com: Server failed</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<br />
Al parecer alguien se esta metiendo con los servidores DNS de estos, whatsapp no responde pero el mensajero Ruso Telegram si lo esta haciendo. Reinicie el telefono a ver si perdia whatsapp pero no fue asi, lo raro es que desde el navegador de la laptop No entra y el CMD esta igual:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><b>> whatsapp.com</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>Servidor: google-public-dns-a.google.com</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>Address: 8.8.8.8</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b><br /></b></span>
<span style="font-family: Courier New, Courier, monospace;"><b>DNS request timed out.</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> timeout was 2 seconds.</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>DNS request timed out.</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> timeout was 2 seconds.</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>DNS request timed out.</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> timeout was 2 seconds.</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"><b>*** google-public-dns-a.google.com no encuentra whatsapp.com: Server failed</b></span><br />
<br />
<br />
Continuara...albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-60808150368479059062016-09-30T12:39:00.000-07:002016-09-30T12:39:04.821-07:00Godaddy Expone Información sensible al usar el mail() de PHPEsto SOLO pasa cuando envías correos desde tu hosting usando la función <u>mail()</u> de <b>PHP</b><br />
<div>
<br />
Cuando tu envías un correo electrónico usando la función de mail de PHP el hosting agrega información de rastreo para los correos con el objetivo de poder rastrear cualquier abuso del mismo y eso esta BIEN, lo que NO esta bien es que agreguen la información en TEXTO PLANO. esto es envían información sensible como:<br />
<ul>
<li>username del CPANEL</li>
<li>UID/GID del Proceso baja el cual se ejecuta el PHP (Un hosting linux claro)</li>
<li>Hosting principal asociado al Hosting</li>
<li>Host de segundario (Si es que existe)...</li>
<li>Ruta desde donde se ejecuta el script PHP</li>
<li>nombre del Script php que envia el correo</li>
</ul>
<div>
Realmente el alcance de la información mostrada puede ser muy util o no dependiendo de que otra información se posea sobre el usuario y/o servidor en cuestión.</div>
<div>
<br /></div>
<div>
Ejemplo:</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><b>X-PHP-Script</b>: <b>(HOST_SECUNDARIO)</b>/index.php for 189.181.131.140</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">X-AntiAbuse: <b>This header was added to track abuse, please include it with any abuse report</b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">X-AntiAbuse: Originator/Caller <b>UID/GID</b> - <b>[123456 666</b>] / [47 12]</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">X-AntiAbuse: Sender Address Domain - p3plcpnl0940.prod.phx3.secureserver.net</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">X-Get-Message-Sender-Via: p3plcpnl0940.prod.phx3.secureserver.net: <b>authenticated_id</b>: <b>username_CPANEL</b>/from_h</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><b>X-Source-Args: /usr/sbin/proxyexec -q -d -s /var/lib/proxyexec/cagefs.sock/socket /bin/cagefs.server</b></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">X-Source-Dir: </span><b style="font-family: "Courier New", Courier, monospace; font-size: small;">(HOST_PRIMARIO)</b><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">:<b>/FULL/PATH/OF/SCRIPT</b></span></div>
<br />
<br />
Como ven la información mostrada por si sola no es tan útil, pero si se llega a combinar con algún otro vector de ataque los resultados podrían ser diferentes.<br />
<div>
<br />
La opción que podrían implementar GODADDY para seguir rastreando los correos es, tomar los valores y guardarlos en alguna de sus bases de datos interna y colocar en los headers del valores diferentes que solo ellos puedan interpretar.<br />
<br />
Saludos!</div>
</div>
</div>
albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-62219363022300884952016-03-27T07:46:00.002-07:002016-03-27T14:51:46.010-07:00Telegram bot in CEleven and half coffe cups were drinked in this project.<br />
<br />
Telegrambot in C is now in github; <a href="https://github.com/albertobsd/libtelegrambot">https://github.com/albertobsd/libtelegrambot</a><br />
<br />
<br />
After download we can edit the sample code to work with the bot.<br />
<br />
Use the github wiki to view all the functions available.<br />
<br />
Example <br />
<br />
<br />
User *user;<br />
user = telegra_getMe();<br />
if(!telegram_bot) {<br />
printf("%s\n",user->username); <br />
} <br />
<br />
Links:<br />
<br />
<br />
<a href="https://github.com/albertobsd/libtelegrambot" target="_blank">telegrambot in C</a><br />
<br />
<a href="https://core.telegram.org/bots/api" target="_blank">Official API for Telegram bot</a>albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-39422546094081496742016-03-17T10:23:00.002-07:002016-03-17T10:23:38.015-07:00Libgcrypt: Sha256 Digest fileContinuando con mis ejemplos para trabajar con libgcrypt, en esta ocacion disponemos de un ejemplo que realiza la funcion sha256 para un archivo dado.<br />
<br />
Existen otras formas de hacarlo distintas librerias y/o funciones, no discutire aqui la eficiencia de la funcion, esta funcion generica recibe como parametros un buffer de entrada, uno de salida y el tipo de algoritmo a usar, que puede ser desde md5 (inseguro), sha1 entre otros.<br />
<br />
Ejemplo: <a href="https://github.com/albertobsd/libgcrypt-examples/blob/master/digestsha256.c" rel="nofollow" target="_blank">digestsha256.c</a> <br />
<br />
Saludos!albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-90656043133281678252016-03-14T10:36:00.001-07:002016-03-14T10:36:34.518-07:00Libgcrypt: Buffer RandomRecientemente he estado trabajando con libgcrypt y me he dado cuenta que hay pocos ejemplos de esta libreria en Internet.<br />
<br />
La Documentacion es muy extensa y esta disponible en linea o para descargar en PDF:<br />
<br />
<a href="https://www.gnu.org/software/libgcrypt/">https://www.gnu.org/software/libgcrypt/</a><br />
<br />
Aqui dejo un pequeño ejemplo para generar un buffer de numeros aleatorios:<br />
<br />
<a href="https://github.com/albertobsd/libgcrypt-examples/blob/master/bufferRandom.c" rel="nofollow" target="_blank">bufferRandom.c</a><br />
<br />
<br />albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-87649455824971488532016-02-29T07:05:00.001-08:002016-02-29T07:34:01.273-08:00Tu Android como tarjeta de red en FreeBSD<div dir="ltr">
Al no contar con alguna red inalámbrica disponible y tampoco una coneccion de red ethernet, solo nos queda disponer de la red movil para navegar.</div>
<div dir="ltr">
Podemos usar una de tres opciones dependiendo de las capacidades de nuestro dispositivo android.</div>
<ul>
<li>Habilitar una red inalámbrica para compartir internet</li>
<li>Compartir el internet usando una conexion bluetooth</li>
<li>Compartie el internet usando el Cable USB</li>
</ul>
<div dir="ltr">
Todas las opciones tienen sus ventajas y desventajas</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
Mi favorito es el de usar la conexion USB.</div>
<div dir="ltr">
<br /></div>
<div dir="ltr">
Al conectar nuestro dispositivo se muestra la opción de habilitar el uso como dispositivo extraible (Memoria USB)<br />
Pero si navegamos a las opciones de compartir internet podremos habilitar la modalidad de USB.</div>
<div dir="ltr">
Tal como se muestra en la imagen a continuación.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://lh3.googleusercontent.com/-v8xIYB7k5Vw/VtReOU1O6mI/AAAAAAAAO8Q/V76F_1purwU/s1600/Screenshot_2016-02-27-09-07-09.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://lh3.googleusercontent.com/-v8xIYB7k5Vw/VtReOU1O6mI/AAAAAAAAO8Q/V76F_1purwU/s640/Screenshot_2016-02-27-09-07-09.png" /> </a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Ahora al momento de conectar el celular en una computadora con windows deberia de detectarlo automáticamente.</div>
<br />
<div class="separator" style="clear: both; text-align: left;">
En FreeBSD mostrara algo similar en la consola de mensajes o con el comando dmesg las ultimas lineas deberian de ser algo similar a a esto:</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<a href="https://lh3.googleusercontent.com/-gOAaABHXhvs/VtReMaHvWsI/AAAAAAAAO8M/TFkrLh9oIRU/s1600/IMG_20160227_090726.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://lh3.googleusercontent.com/-gOAaABHXhvs/VtReMaHvWsI/AAAAAAAAO8M/TFkrLh9oIRU/s640/IMG_20160227_090726.jpg" /></a>
<br />
<div class="separator" style="clear: both; text-align: left;">
Solo bastara ejecutar <b>dhclient</b> para obtener una direccion IP y comenzar a navegar.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
En caso de que no te detecte el distotivo Android recuarda que es necesario tener habilitado en el kernel la opcion de <b>urndis</b> desde el archivo de configuracion del kernel<b><br /></b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b><span style="font-family: "Courier New",Courier,monospace;">device urndis # Android Tethering</span></b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
O con el comando <b>kldload</b> </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "Courier New",Courier,monospace;"><b># kldload urndis </b></span></div>
albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-39324118268835413462016-02-25T18:59:00.001-08:002016-02-25T18:59:09.721-08:00DD-WRT + SSH + Authorized KeysUno de los gadgets que nunca me arrepentire de comprar es el router WRT54G este estuche de monerias tiene una amplia gama de usos. <br />
<br />
He configurado mi router con DDWRT y en esta ocacion solo mostrare como configurar el acceso SSH al router sin necesidad de ingresar el password del usuario, esto es util si estamos tratando de realizar un script que se conecte al SSH o en otro uso si queremos que nuestro cliente ssh se reconecte sin pedir el password cada vez que se desconecte con ayuda de la herramienta autossh.<br />
<br />
Lo primero que tenemos que tener es generar nuestro par de llaves publicas/privadas exclusivos para nuestro ssh<br />
<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">ssh-keygen -t rsa
</span><br />
<br />
si ejecutamos el comando veremos algo como lo que se muestra a continuacion <br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">Alberto@Host:~> ssh-keygen -t rsa
Generating public/private rsa key pair.<br />
Enter file in which to save the key (/home/Alberto/.ssh/id_rsa): <br />
Created directory '/home/Alberto/.ssh'.<br />
Enter passphrase (empty for no passphrase): <br />
Enter same passphrase again: <br />
Your identification has been saved in /home/Alberto/.ssh/id_rsa.<br />
Your public key has been saved in /home/Alberto/.ssh/id_rsa.pub.<br />
The key fingerprint is:<br />
3e:4b:05:80:3a:9f:96:7c:3b:ad:e9:58:34:bc:37:e4 Alberto@Host<br />
</span><br />
<br />
<br />
Lo que se tiene que hacer a continuacion es abrir el archivo "<span style="font-family: "courier new" , "courier" , monospace;">/home/Alberto/.ssh/id_rsa.pub</span>" y copiar su contenido al campo respectivo en la pagina de nuestro DD-WRT en la seccion de servicios el campo llamado "<b>authorized key</b>" y asi cada vez que nos conectemos desde nuestra computadora y con el usuario con el cual ejecutamos ssh-keygen no nos pedira password nuestro router<br />
<br />
El proceso debe de ser reptido para las computadoras que queramos autorizar.<br />
<br />
Fuentes:
<br />
<br />
<a href="http://www.linuxproblem.org/art_9.html">http://www.linuxproblem.org/art_9.html</a><br />
<a href="https://www.dd-wrt.com/wiki/index.php/SSH">https://www.dd-wrt.com/wiki/index.php/SSH</a>albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-10228261029595203032016-01-01T16:17:00.002-08:002016-01-01T16:17:25.369-08:00[Programa C] Multiplicacion de numeros muy grandesRecientemente multiplicanto numeros muy grandes uno se enfrenta al problema de los tipos de datos estandar en las computadoras muchas veces no dan abasto para numeros muy grandes.<br />
<br />
Claro ya existen librerias que hacen lo antes mencionado pero uno como programador deberia de hacer algo sencillo por su cuenta como ejercicio recreativo.<br />
<br />
El problema surgio al estar calculando las permutaciones posibles en el juego de Bingo siendo estas en su posicion numero 30 con 60 numeros un total poco mas de 31 octillones.<br />
<br />
Al principio trate de calcular los numeros a mano pero al final del proceso no sabras se cometistes algun error en el proceso de multiplicar 30 numeros continuos, asi que para comprobar los numeros a los cuales llegue fue necesario programar un programa que haga lo mismo.<br />
<br />
El programa basicamente imita la forma de multiplicacion manual.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-p4B9qSKtP3Q/VocF7hFrKxI/AAAAAAAAOQM/zoQ5LAMWsi8/s1600/multi.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="273" src="http://2.bp.blogspot.com/-p4B9qSKtP3Q/VocF7hFrKxI/AAAAAAAAOQM/zoQ5LAMWsi8/s640/multi.png" width="640" /></a></div>
<br />
Teniendo este algoritmo no es dificil hacer una funcion que tenga dos parametros como factores y devuelva un apuntador a la cadena de texto que contiene el producto de la multiplicacion.<br />
<br />
Y ahora si, podemos hacer un programa que me devuelva el numero de permutaciones posibles de los numeros en el juego de bingo.<br />
<br />
Y el resultado es el siguiente.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-yNwqyeXsPS0/VocVuXhLemI/AAAAAAAAOQc/J4lqC-E-jcg/s1600/MultiB.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="292" src="http://1.bp.blogspot.com/-yNwqyeXsPS0/VocVuXhLemI/AAAAAAAAOQc/J4lqC-E-jcg/s640/MultiB.png" width="640" /></a></div>
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">60 x 59 = 3540<br />3540 x 58 = 205320<br />205320 x 57 = 11703240<br />11703240 x 56 = 655381440<br />655381440 x 55 = 36045979200<br />36045979200 x 54 = 1946482876800<br />1946482876800 x 53 = 103163592470400<br />103163592470400 x 52 = 5364506808460800097324143840000<br />5364506808460800097324143840000 x 51 = 273589847231500804963531335840000<br />273589847231500804963531335840000 x 50 = 13679492361575040248176566792000000<br />13679492361575040248176566792000000 x 49 = 670295125717176972160651772808000000<br />670295125717176972160651772808000000 x 48 = 32174166034424494663711285094784000000<br />32174166034424494663711285094784000000 x 47 = 1512185803617951249194430399454848000000<br />1512185803617951249194430399454848000000 x 46 = 69560546966425757462943798374923008000000<br />69560546966425757462943798374923008000000 x 45 = 3130224613489159085832470926871535360000000<br />3130224613489159085832470926871535360000000 x 44 = 137729882993522999776628720782347555840000000<br />137729882993522999776628720782347555840000000 x 43 = 5922384968721488990395034993640944901120000000<br />5922384968721488990395034993640944901120000000 x 42 = 248740168686302537596591469732919685847040000000<br />248740168686302537596591469732919685847040000000 x 41 = 10198346916138404041460250259049707119728640000000<br />10198346916138404041460250259049707119728640000000 x 40 = 407933876645536161658410010361988284789145600000000<br />407933876645536161658410010361988284789145600000000 x 39 = 15909421189175910304677990404117543106776678400000000<br />15909421189175910304677990404117543106776678400000000 x 38 = 604558005188684591577763635356466638057513779200000000<br />604558005188684591577763635356466638057513779200000000 x 37 = 22368646191981329888377254508189265608128009830400000000<br />22368646191981329888377254508189265608128009830400000000 x 36 = 805271262911327875981581162294813561892608353894400000000<br />805271262911327875981581162294813561892608353894400000000 x 35 = 28184494201896475659355340680318474666241292386304000000000<br />28184494201896475659355340680318474666241292386304000000000 x 34 = 958272802864480172418081583130828138652203941134336000000000<br />958272802864480172418081583130828138652203941134336000000000 x 33 = 31623002494527845689796692243317328575522730057433088000000000<br />31623002494527845689796692243317328575522730057433088000000000 x 32 = 1011936079824891062073494151786154514416727361837858816000000000<br />1011936079824891062073494151786154514416727361837858816000000000 x 31 = 31370018474571622924278318705370789946918548216973623296000000000</span></span><br />
<br />
<br />
Saludos!<br />
<br />albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-59214607524274501892015-09-13T13:34:00.003-07:002015-09-14T21:34:48.642-07:00Clave WPA2 por Defecto de equipos TotalPlay (Huawei HG8245H)La clave WPA2 por defecto de equipos Huawei HG8245H Instalados por total play esta dada por parte del SSID (Nombre de la red Wireless) y parte de la MAC Address<br />
<br />
Donde la MAC es: XX:XX:XX:AB:CD:XX<br />
y el SSID es:<br />
<br />
Totalplay-EFGH<br />
<br />
La clave para este caso ficticio es: ABCDEFGH<br />
<br />
Este un caso especifico al parecer no se cumple para todos los router, estoy checando que el equipo de Websec ya tiene el algoritmo en su pagina de <a href="http://routerpwn.com/" target="_blank">Routerpwn</a> <br />
<br />
Saludos.albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com12tag:blogger.com,1999:blog-7790310044037605252.post-51580578318881687022015-09-08T18:27:00.002-07:002015-09-08T18:27:57.424-07:00FreeBSD mini-memstickDescargando FreeBSD 10.2 para USB.<br />
<br />
<a href="ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/i386/ISO-IMAGES/10.2/">ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/i386/ISO-IMAGES/10.2/</a><br />
<br />
Usare para tratar de actualizar el viejo ordenador con Ubuntu y usuarlo como servidor de archivos en la pagina de megafirmware.<br />
<br />
Quiero que tenga solo PHP para ejecutar algunos script, additional a esto un servidor de archivos torrents.<br />
<br />
<br />albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0tag:blogger.com,1999:blog-7790310044037605252.post-64179679035658470112015-05-05T17:32:00.001-07:002015-05-05T18:30:28.905-07:00Realtek RTL8188ETVPictures of the Realtek Board on tablet.<div><div><br></div><div><div class="separator" style="clear: both;"><a href="https://lh3.googleusercontent.com/-0kJb-F8NR6E/VUlhLWYrejI/AAAAAAAANr4/jMljLkO_ygw/s640/blogger-image-836420817.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://lh3.googleusercontent.com/-0kJb-F8NR6E/VUlhLWYrejI/AAAAAAAANr4/jMljLkO_ygw/s640/blogger-image-836420817.jpg"></a></div><br></div><div><div class="separator" style="clear: both;"><a href="https://lh3.googleusercontent.com/-odTaSyGL4pg/VUlhHWD9pBI/AAAAAAAANro/3mv9GcDiw5s/s640/blogger-image--1794428338.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://lh3.googleusercontent.com/-odTaSyGL4pg/VUlhHWD9pBI/AAAAAAAANro/3mv9GcDiw5s/s640/blogger-image--1794428338.jpg"></a></div><div class="separator" style="clear: both;"><br></div><div class="separator" style="clear: both;"><a href="https://lh3.googleusercontent.com/-LWpys8mZslo/VUlhEcv6d6I/AAAAAAAANrg/ZxMhvKI9_vg/s640/blogger-image-1844301498.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://lh3.googleusercontent.com/-LWpys8mZslo/VUlhEcv6d6I/AAAAAAAANrg/ZxMhvKI9_vg/s640/blogger-image-1844301498.jpg"></a></div><br></div><div><div class="separator" style="clear: both;"><a href="https://lh3.googleusercontent.com/-_lZd9iT6nFM/VUlhI-lKEjI/AAAAAAAANrw/zWCARfRYZBk/s640/blogger-image-1018818988.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://lh3.googleusercontent.com/-_lZd9iT6nFM/VUlhI-lKEjI/AAAAAAAANrw/zWCARfRYZBk/s640/blogger-image-1018818988.jpg"></a></div><br></div></div>albertobsdhttp://www.blogger.com/profile/17715578183442588302noreply@blogger.com0