|
Mostrar Temas
|
Páginas: [1] 2 3
|
1
|
Programación / Ingeniería Inversa / Ayuda para identificar algoritmo de compresion zlib
|
en: 24 Diciembre 2021, 16:26 pm
|
Hola, tengo un archivo que fue comprimido con zlib y estoy tratando de averiguar el método que fue utilizado para comprimirlo. Este archivo en particular usa un nivel 9 de compresión, y por lo que pude descifrar la entrada se divide en bloques de 8KiB, y se hace Z_SYNC_FLUSH luego de comprimir cada bloque, pero cada 8 bloques el algoritmo parece hacer otra cosa. Este es el código que escribí para descomprimir y comprimir el archivo. Para descomprimir funciona bien, pero solo comprime correctamente los primeros 7 bloques del archivo. import sys import zlib # python3 zlib-flate.py -d output.bin input.bin # python3 zlib-flate.py -9 input.bin output_test.bin def usage(): print("Usage:") print(f"python3 {sys.argv[0]} -[1-9,d] input.bin output.bin") exit() def main(): argc = len(sys.argv) if argc != 4: usage() try: if sys.argv[1] == "-d": # Decompress file with open(sys.argv[2], "rb") as input_file, open(sys.argv[3], "wb") as output_file: data = input_file.read() comp_obj = zlib.decompressobj() data_plain = comp_obj.decompress(data) output_file.write(data_plain) else: # Compress file level = -int(sys.argv[1]) if level < 1 or level > 9: print("Invalid compression level") with open(sys.argv[2], "rb") as input_file, open(sys.argv[3], "wb") as output_file, open("output.bin", "rb") as test_file: comp_obj = zlib.compressobj(level) data = input_file.read(8 * 1024) # Read block of 8KiB i = 1 while data != b"": data_zip = comp_obj.compress(data) data_zip += comp_obj.flush(zlib.Z_SYNC_FLUSH) # Check if compressed data differs lenght = len(data_zip) data_test = test_file.read(lenght) if data_zip == data_test: print(f"Block #{i}: correctly compressed") else: print(f"Block #{i}: invalid data") exit() output_file.write(data_zip) data = input_file.read(8 * 1024) i = i + 1 print("File compressed correctly!") except (IOError, ValueError) as error: print("Invalid parameters") main()
Archivo comprimido con zlib: https://mega.nz/file/8a5C1SyQ#xqy9nCycTrWfrnwuvWa39xd128s9huSFuf8kOr6kK8Q
|
|
|
2
|
Programación / Programación General / Programa que imprime un número entre 0 y un billón como texto [SWI-Prolog]
|
en: 8 Octubre 2020, 23:34 pm
|
Siempre quise hacer un programa que dado un numero lo imprima como texto, por ejemplo 132 -> ciento treinta y dos, pero nunca me puse, hasta hoy que vi gramáticas de cláusulas definidas en programación lógica y en poco más de media hora salió. Los casos más difíciles de hacer fueron por ejemplo 16 (dieciséis), 21 (veintiuno) que son una única palabra y 1002 (mil dos) que no es “un mil dos” o “uno mil dos”. Como no chequeo que el resto sea distinto de cero pueden generarse casos como “40 -> cuarenta y cero” o “41 -> cuarenta y cero y uno, cuarenta y cero… y cero y uno” que son quitados con el operador cut (!). Les dejo acá el código y algunos ejemplos. 17 diecisiete 29 veintinueve 547 quinientos cuarenta y siete 1234 mil doscientos treinta y cuatro 3597426 tres millones quinientos noventa y siete mil cuatrocientos veintiséis 742258963 setecientos cuarenta y dos millones doscientos cincuenta y ocho mil novecientos sesenta y tres 100000000000 cien mil millones 999999999999 novecientos noventa y nueve mil novecientos noventa y nueve millones novecientos noventa y nueve mil novecientos noventa y nueve 1000000000000 un billon 31000 treinta y uno mil* * Y aquí encontré un bug, debería decir treinta y un mil % Imprime un numero como texto print_number(N) :- numero(N, L, []), !, atomic_list_concat(L, ' ', A), writeln(A). % Crea una lista [0..N] create_list(N, L) :- findall(X, between(0, N, X), L). % Imprime los numeros entre 0 y N print_numbers(N) :- create_list(N, L), print_aux(L). print_aux([]). print_aux([X|L]) :- print_number(X), print_aux(L). % Convierte un numero en una lista de palabras % ej: numero(132, L, []) -> [ciento, treinta, y, dos]. numero(0) --> [cero]. numero(1) --> [uno]. numero(2) --> [dos]. numero(3) --> [tres]. numero(4) --> [cuatro]. numero(5) --> [cinco]. numero(6) --> [seis]. numero(7) --> [siete]. numero(8) --> [ocho]. numero(9) --> [nueve]. numero(10) --> [dies]. numero(11) --> [once]. numero(12) --> [doce]. numero(13) --> [trece]. numero(14) --> [catorce]. numero(15) --> [quince]. numero(20) --> [veinte]. numero(30) --> [treinta]. numero(40) --> [cuarenta]. numero(50) --> [cincuenta]. numero(60) --> [sesenta]. numero(70) --> [setenta]. numero(80) --> [ochenta]. numero(90) --> [noventa]. numero(100) --> [cien]. % Convertir numeros entre 16 y 19 numero(N) --> {N > 15, N < 20, U is N mod 10, numero(U, X, []), atomic_list_concat([dieci|X], S)}, [S]. % Convertir numeros entre 21 y 29 numero(N) --> {N > 20, N < 30, U is N mod 10, numero(U, X, []), atomic_list_concat([veinti|X], S)}, [S]. % Convertir numeros entre 31 y 99 numero(N) --> {N > 30, N < 100, D is N - (N mod 10), U is N mod 10}, numero(D), [y], numero(U). numero(200) --> [doscientos]. numero(300) --> [trescientos]. numero(400) --> [cuatrocientos]. numero(500) --> [quinientos]. numero(600) --> [seiscientos]. numero(700) --> [setecientos]. numero(800) --> [ochocientos]. numero(900) --> [novecientos]. numero(1000) --> [mil]. % Convertir numeros entre 101 y 199 numero(N) --> {N > 100, N < 200, D is N mod 100}, [ciento], numero(D). % Convertir numeros entre 201 y 999 numero(N) --> {N > 200, N < 1000, C is N - (N mod 100), D is N mod 100}, numero(C), numero(D). % Convertir numeros entre 1001 y 1999 numero(N) --> {N > 1000, N < 2000, D is N mod 1000}, [mil], numero(D). % Convertir numeros entre 2000 y 999 000 que terminan en 000, ej: 7000 numero(N) --> {N >= 2000, N =< 999000, C is N div 1000, D is N mod 1000, D = 0}, numero(C), [mil]. % Convertir numeros entre 2001 y 999 999 numero(N) --> {N > 2000, N < 1000000, C is N div 1000, D is N mod 1000}, numero(C), [mil], numero(D). numero(1000000) --> [un, millon]. % Convertir numeros entre 1 000 001 y 1 999 999 numero(N) --> {N > 1000000, N < 2000000, D is N mod 1000000}, [un, millon], numero(D). % Convertir numeros entre 2 000 000 y 999 999 000 000 que terminan en 000 000, ej: 7 000 000 numero(N) --> {N >= 2000000, N =< 999999000000, C is N div 1000000, D is N mod 1000000, D = 0}, numero(C), [millones]. % Convertir numeros entre 2000001 y 999 999 999 999 numero(N) --> {N > 2000000, N < 1000000000000, C is N div 1000000, D is N mod 1000000}, numero(C), [millones], numero(D). numero(1000000000000) --> [un, billon].
Para ejecutar instalan SWI-Prolog Guardan el código como “numtext.pl” Abren cmd en el directorio donde guardaron el archivo > swipl numtext.pl ?- print_number(N). # donde N es el número a mostrar
|
|
|
3
|
Programación / Programación C/C++ / Ayuda con HTML Proxy en C
|
en: 11 Febrero 2020, 17:39 pm
|
Supongamos que tengo una página web en un servidor Apache corriendo en 192.168.1.1:80 y quiero acceder a él desde 127.0.0.1:8080 (las ip y puertos son solo de ejemplo). El siguiente programa me muestra la página pero las imágenes no cargan, tampoco puedo hacer login. No se que es lo que tengo mal. // g++ -Wall -Werror tcp_proxy.cpp -o tcp_proxy -lpthread -lws2_32 #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <winsock2.h> #include <ws2tcpip.h> #define Localhost "127.0.0.1" #define ProxyPort 8080 #define HTTP_Server "192.168.1.1" #define HTTP_Port "80" #define MaxUsersQueue 10 #define MaxMsgSize 2048 struct sockets { int source; int dest; }; void* conectarProxy(void*); void* pushData(void*); int main(int argc, char* argv[]) { WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); int proxy_socket = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(Localhost); if (argc < 2) server_addr.sin_port = htons(ProxyPort); else // Usar puerto pasado desde la terminal server_addr.sin_port = htons(atoi(argv[1])); int server_addr_size = sizeof(server_addr); bind(proxy_socket, (sockaddr*) &server_addr, server_addr_size); listen(proxy_socket, MaxUsersQueue); while (true) { sockaddr_in client_addr; int client_addr_size = sizeof(client_addr); int socket_client = accept(proxy_socket, (sockaddr*) &client_addr, &client_addr_size); pthread_t hilo_conectarProxy; pthread_create(&hilo_conectarProxy, NULL, conectarProxy, &socket_client); } close(proxy_socket); return 0; } void* conectarProxy(void* sc_param) { int socket_client = *((int*)sc_param); int httpServerSock = socket(AF_INET, SOCK_STREAM, 0); addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; addrinfo* res; getaddrinfo(HTTP_Server, HTTP_Port, &hints, &res); connect(httpServerSock, res->ai_addr, res->ai_addrlen); freeaddrinfo(res); sockets* cliente_proxy = new sockets{socket_client, httpServerSock}; pthread_t hilo_cliente_proxy; pthread_create(&hilo_cliente_proxy, NULL, pushData, cliente_proxy); sockets* proxy_cliente = new sockets{httpServerSock, socket_client}; pthread_t hilo_proxy_cliente; pthread_create(&hilo_proxy_cliente, NULL, pushData, proxy_cliente); pthread_join(hilo_cliente_proxy, NULL); pthread_join(hilo_proxy_cliente, NULL); return NULL; } void* pushData(void* args) { sockets* src_dst = (sockets*)args; int src = src_dst->source; int dst = src_dst->dest; char* data = new char[MaxMsgSize]; char buffer[MaxMsgSize]; while (true) { strcpy(data, ""); strcpy(buffer, ""); int msg_size = 0; do { msg_size += recv(src, buffer, MaxMsgSize, 0); if (msg_size == 0) break; if (msg_size == -1) break; printf("%d->%d Recibido: %d bytes\n", src, dst, msg_size); strcat(data, buffer); } while (strchr(data, '\n') == NULL); if (msg_size == -1) break; int sent_msg_size = send(dst, data, msg_size, 0); printf("%d->%d Enviado: %d bytes\n", src, dst, msg_size); if (sent_msg_size == -1) break; } delete (sockets*)args; delete[] data; close(src); close(dst); return NULL; }
|
|
|
4
|
Programación / Scripting / [PYTHON] Como crear conjunto a partir de lista de tuplas por clave?
|
en: 29 Marzo 2019, 03:07 am
|
Como crear conjunto a partir de lista de tuplas por clave? Por ejemplo tengo la siguiente lista de tuplas x = [('El', 'auto'), ('el', 'auto'), ('un', 'auto'), ('algun', 'auto'), ('Los', 'camiones'), ('UN', 'auto')]
Y quiero obtener la siguiente: y = [('el', 'auto'), ('Los', 'camiones')]
En lugar de "el" podria estar cualquiera de los determinantes usados anteriormente. He intentado usar set() pero no se como hacer para que tome solo el segundo parametro para crear el conjunto.He implementado el siguiente codigo pero es muy ineficiente, basicamente busca todas las ocurrencias para quedarse con una sola. nombres = [('El', 'auto'), ('el', 'auto'), ('un', 'auto'), ('El', 'camion')] pares = [] palabras = list(set(x[1] for x in nombres)) for i in range(0, len(palabras)): j = [det[0] for det in nombres if det[1] == palabras[i]] pares = pares + [(j[0], palabras[i])] print(pares)
|
|
|
5
|
Programación / Programación C/C++ / [AYUDA] Como se de que tipo se creo una clase que deriba de otra
|
en: 16 Marzo 2019, 05:01 am
|
#include <random> #include <cstdio> #include <stdexcept> class Vehiculo { public: virtual ~Vehiculo() { }; // Clase abstracta }; class Automovil : public Vehiculo { public: int matricula = 4409; }; class Bicicleta : public Vehiculo { public: int cambios = 18; }; void MostrarAtrb(const Vehiculo& vehiculo) { try { const Automovil& car = dynamic_cast<const Automovil&>(vehiculo); printf("Es un Automovil con matricula: %d\n", car.matricula); } catch(std::bad_cast &e) { printf("Error %s\n", e.what()); } try { const Bicicleta& bici = dynamic_cast<const Bicicleta&>(vehiculo); printf("Es una Bicicleta con %d cambios\n", bici.cambios); } catch(std::bad_cast &e) { printf("Error %s\n", e.what()); } } int main() { Vehiculo vehiculo; if (rand() % 2 == 0) vehiculo = Automovil(); else vehiculo = Bicicleta(); MostrarAtrb(vehiculo); // Como se de que tipo se creo el objeto??? return 0; }
Ambas conversiones de tipo dan error.
|
|
|
6
|
Programación / Programación C/C++ / Desofuscar codigo
|
en: 22 Noviembre 2018, 03:17 am
|
Queria compartir el siguiente codigo que genera un Donut 3D (solo funciona en la terminal de Linux o la de MinGW) y mi intento por desofuscarlo. 0,B=0,i,j,z[1760];char b[ 1760];printf("\x1b[2J");for(;; ){memset(b ,32,1760);memset (z ,0,7040) ;for(j=0;6.28>j;j+=0.07)for(i=0;6.28 >i ;i +=0.02){float c =sin(i ),d =cos(j ),e = h *e +f *g +5),l =cos (i ),m =cos(B ),n =s\ in(B),t=c*h*g-f* e;int x=40+30*D* (l*h*m-t*n),y= 12+15*D*(l*h*n +t*m),o=x+80*y, N=8*((f*e-c*d*g )*m-c*d*e-f*g-l *d*n);if(22>y&& y>0&&x>0&&80>x&&D>z[o]){z[o]=D;;;b[o]= ".,-~:;=!*#$@"[N>0?N:0];}}/*#****!!-*/ printf("\x1b[H");for (k =0;1761>k ;k ++) 0.02;}}/*****####*******!!=;:~ ~::==!!!**********!!!==::- .,~~;;;========;;;:~-. ..,--------,*/
#include <math.h> #include <stdio.h> #include <string.h> #define PI 3.14 #define HEIGHT 22 #define WIDTH 80 const float R2 = 2; // Distancia del centro del Toroide a la mitad: ( ) |---(-. ) const char* illumination = ".,-~:;=!*#$@"; int main(){ float zbuffer[HEIGHT][WIDTH]; char framebuffer[HEIGHT][WIDTH]; float A = 0, C = 0; // Ejes X y Z sobre los que rota el Toroide printf("\x1b[2J"); // Borrar Pantalla while (true) { memset(zbuffer, 0.0, HEIGHT * WIDTH * sizeof(float)); // Fondo a distancia infinita memset(framebuffer, ' ', HEIGHT * WIDTH * sizeof(char)); // Pantalla vacia for (float B = 0; B < 2 * PI; B += 0.07) // Eje Y sobre el que rota el Toroide for (float phi = 0; phi < 2 * PI; phi += 0.02) { // Eje del toroide (perpendicular al centro) float sin_phi = sin(phi), cos_phi = cos(phi), sinA = sin(A), cosA = cos(A), sinB = sin(B), cosB = cos(B), sinC = sin(C), cosC = cos(C), // Solo otro par de valores que precalculamos h = cosB + R2, t = h * sin_phi * cosA - sinA * sinB, // Distancia inversa del observador al centro del Toroide D = 1 / (h * sin_phi * sinA + cosA * sinB + 5); int // Posicion de la pantalla donde se renderiza un punto del Toroide x = 40 + 30 * D * (h * cos_phi * cosC - sinC * t), y = 12 + 15 * D * (h * cos_phi * sinC + cosC * t), /* La luz proviene de arriba y atras del observador (0, 1, -1) que tiene modulo 2, hay 12 tonos de luz: 0..11, 11 / sqrt(2) = 8 L = 8 * (y - z); */ L = 8 * ((sinA * sinB - sin_phi * cosA * cosB) * cosC - sin_phi * sinA * cosB - cosA * sinB - cos_phi * cosB * sinC); // LAS MATRICES TIENEN INDICES i VERTICAL Y j HORIZONTAL // MIENTRAS QUE LAS GRAFICAS TIENEN x HORIZONTAL E y VERTICAL if (x > 0 && x < WIDTH && y > 0 && y < HEIGHT && zbuffer[y][x] < D) { /* Si el punto actual es mas cercano a la pantalla que alguno calculado previamente entonces sobrescribir al anterior */ if (L < 0) L = 0; // Sombra framebuffer[y][x] = illumination[L]; zbuffer[y][x] = D; // Guardar profundidad } } printf("\x1b[H"); // Mover el cursor a la esquina superior izquierda for (int i = 0; i < HEIGHT; i++) { for (int j = 0; j < WIDTH; j++) putchar(framebuffer[i][j]); // Mostrar Toroide putchar('\n'); } A += 0.04; C += 0.02; } return 0; }
|
|
|
7
|
Sistemas Operativos / GNU/Linux / Gestor de descargas para Linux
|
en: 5 Noviembre 2018, 15:18 pm
|
Busco un gestor de descarga para Linux que sea portable (no tengo permisos de root para instalarlo) sin interfax grafica (que se ejecute desde terminal) y que me permita descargar de servidores como Mega, 1fichier o Google Drive. Algo como MiPony pero que pueda pasar los links desde la terminal.
|
|
|
8
|
Programación / Programación General / [AYUDA] ¿Cómo hacer este código más eficiente?
|
en: 16 Octubre 2018, 00:12 am
|
El siguiente codigo se ejecuta en orden lineal con respecto al tamaño del arreglo A, mi pregunta es cómo hacer dicho codigo más eficiente, digamos O(log n), la idea que tengo es hacer busqueda binaria, es decir, dividir A a la mitad ((i-1) / 2) y buscar en cada mitad. Pero: - Si encuentro un i > 0 en la primera mitad deberia buscar en la segunda. (podria existir un i mayor)
- Si no encuentro un i > 0 en la segunda mitad debería buscar en la primera si no lo hice antes. (ya que podria existir un i > 0)
Por lo que sigue siendo O(n) en el peor caso, quiza no sea posible implementarlo en O(log n)/* A[1..n] esta ordenado de menor a mayor * Devuelve el mayor indice i' menor o igual a i tal que A[i'] <= c * o cero si no se encuentra. Cota superior asintotica: O(n) */ void buscarIndice(const uint* A, uint &i, const uint c) { while (i > 0 && A[i] > c) i--; }
El siguente codigo es O(n^2), lo que si es seguro es que como A está ordenado es posible implementarlo en O(n log n) (La demostración queda a cargo del lector) ¿Alguna idea de por donde empezar? for (uint j = 1; j <= n; j++) { uint i = j; // No es ortodoxo modificar j buscarIndice(A, i, c); hacerAlgoUtilCon(i); }
|
|
|
9
|
Programación / Programación C/C++ / ¿Cómo hallar una Permutacion ordenada con MergeSort?
|
en: 11 Octubre 2018, 01:12 am
|
Dado un arreglo desordenado con n elementos, el siguiente código retorna una permutación tal que al aplicarla al arreglo original los elementos quedan ordenados. #include <stdio.h> typedef unsigned int uint; void Swap(int &a, int &b) { int t = a; a = b; b = t; } int* BubbleSort(const int* A, uint n) { int* P = new int[n]; for (uint i = 0; i < n; i++) P[i] = i; bool ordenado; do { ordenado = true; for (uint i = 1; i < n; i++) if (A[P[i-1]] > A[P[i]]) { Swap(P[i-1], P[i]); ordenado = false; } } while (!ordenado); return P; } int main() { uint n; printf("Ingrese la cantidad de numeros: "); scanf("%u", &n); printf("Ingrese los numeros:\n"); int* A = new int[n]; for (uint i = 0; i < n; i++) scanf("%d", &A[i]); int* P = BubbleSort(A, n); printf("Los numeros ordenados son:\n"); for (uint i = 0; i < n; i++) printf("%d ", A[P[i]]); printf("\n"); delete[] A; delete[] P; return 0; }
Pero lo hace en tiempo O(n^2), en cambio el siguiente codigo: https://www.geeksforgeeks.org/merge-sort/ retorna el arreglo ordenado en tiempo O(n log(n)) ¿Cómo puedo modificar MergeSort para obtener una permutación ordenada en lugar de ordenar el propio arreglo?
|
|
|
10
|
Sistemas Operativos / Windows / [AYUDA!!!] Mover partición "Reservado para el sistema"
|
en: 16 Mayo 2018, 00:15 am
|
Hola, tengo tres unidades de almacenamiento: - SSD 120GB Sistema Operativo
- HDD 500GB (particion de 100MB Reservado para el sistema)
- HDD 1TB
¿Cómo puedo mover la particion: "Reservado para el sistema" 100MB NTFS Correcto (Sistema, Activo, Partición Primaria) del disco de 500GB a alguno de los otros sin tener que reinstalar el Sistema Operativo? Puedo redimensionar los otros dos discos y formatear el de 1TB si fuera necesario, uso Windows 7 Ultimate SP1 y dispongo de la ISO. El problema que tengo es que si quito el disco de 500GB me sale el siguiente mensaje luego de la BIOS: "Reboot and Select proper Boot device or Insert Boot Media in selected Boot device and press a key"
|
|
|
|
|
|
|