elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Tutorial básico de Quickjs


  Mostrar Temas
Páginas: [1]
1  Programación / .NET (C#, VB.NET, ASP) / Sugerencias para GUI en aplicación sniffer MDB en: 4 Enero 2024, 10:17 am
Actualmente estoy inmerso en el desarrollo de una aplicación que realiza el seguimiento del tráfico MDB/ICP de máquinas expendedoras. Además de exhibir los datagramas, la aplicación ofrece diagnósticos adicionales cuando la máquina cuenta con una terminal TPV.

La aplicación se compone esencialmente de dos partes: el núcleo reside en un microcontrolador que, al conectarse al bus MDB, genera el "paquete de datos" y también imprime en bruto a través de la consola de depuración lo que está capturando. Posteriormente, diseñé una interfaz gráfica de usuario (una aplicación WinForms) que lee la información proporcionada por el micro a través del puerto serie, la almacena en una base de datos SQLite y la presenta en un GridView. Para obtener detalles adicionales, basta con hacer doble clic en la fila correspondiente de la tabla.

He implementado pequeñas funcionalidades, tales como:

    1. La capacidad de filtrar por tipo de periférico (dispositivo sin efectivo, validador de billetes, etc.).
    2. Identificación del estado del dispositivo sin efectivo asociado con cada datagrama, que funciona como una máquina de estados finitos.
    3. Generación de documentos en formato CSV, con funciones tanto para importar como para exportar listas de datos en CSV.
    4. Carga eficiente de datos previamente almacenados desde el archivo .db correspondiente en cada lectura.

Sin embargo, me encuentro en un punto donde agoté mis ideas, y admito que mis habilidades en el diseño de la interfaz de usuario dejan mucho que desear. No me siento satisfecho con la estética de la interfaz actual. Por lo tanto, estoy abierto a nuevas sugerencias para mejorar la funcionalidad y hacer que el programa sea más atractivo visualmente. ¿Alguna idea para incorporar nuevas características o mejorar la apariencia de la interfaz?


2  Programación / Programación C/C++ / Revelando el Intrigante Arte de la Ruleta: Desentrañando el Hack de la Cadena de Markov en: 18 Diciembre 2023, 18:37 pm
Saludos a la comunidad apasionada de la ruleta. Hoy, me complace compartir con ustedes un fascinante enfoque que ha capturado la atención de los entusiastas del juego y los amantes de las estrategias ingeniosas: el hack de la cadena de Markov en la ruleta. ¿Qué sucede cuando la probabilidad se encuentra con la emoción del juego? La respuesta yace en la asombrosa intersección entre la teoría de la cadena de Markov y la rueda giratoria del destino.

Antes de sumergirnos en los detalles, tomémonos un momento para apreciar la magia que impulsa este hack. La cadena de Markov, conocida por su capacidad para modelar sistemas estocásticos, se convierte en una aliada inesperada en el universo impredecible de la ruleta. ¿Será esta la clave para desbloquear patrones ocultos en la ruleta? Descubramos juntos si este hack es un truco astuto o una revelación genuina.

LA CADENA DE MARKOV

Una cadena de Markov es un modelo matemático que describe una secuencia de eventos donde la probabilidad de que ocurra un evento particular depende solo del evento inmediatamente anterior. Es decir, en una cadena de Markov, el futuro solo está condicionado por el presente, y no retiene información sobre el pasado más allá del último estado.

Matemáticamente, la propiedad de Markov se expresa de la siguiente manera:


portal foto

En palabras simples, esta fórmula indica que la probabilidad de pasar al estado s en el próximo paso, dado el estado actual st, no depende de la secuencia completa de estados anteriores, sino solo del estado actual.

LA MATRIZ DE TRANSICIÓN

La matriz de transición, P, es una matriz que representa las probabilidades de transición entre los estados de una cadena de Markov. En una cadena con n estados, P es una matriz n×n, y Pij​ representa la probabilidad de pasar del estado i al estado j.

portal foto

CÁLCULO DEL VECTOR DE ESTADOS

Si tenemos un vector de probabilidades inicial vt​ en el paso t, la actualización del vector de probabilidades al paso t+1 se realiza multiplicando el vector por la matriz de transición P.


portal foto

EL CÓDIGO!

Código
  1. /* ROULETTE MARKOV CHAIN SIMULATION by profinet
  2.  
  3.  In the ethereal realm of Markov chains, we delve into the enchanting world
  4.  of probabilities governing the game of Roulette. Before we unveil the magic
  5.  woven by this C program, let's unravel the mathematical essence of a Markov chain.
  6.  
  7.  MARKOV CHAIN:
  8.  
  9.  A Markov chain is a stochastic model that describes a sequence of events where
  10.  the probability of transitioning to any particular state depends solely on the
  11.  current state and time elapsed, not on the sequence of events that preceded it.
  12.  This memoryless property is known as the Markov property.
  13.  
  14.  - State Space: Sets A, B, C, and D represent the states in our Roulette Markov
  15.  chain. Each state corresponds to a range of numbers on the Roulette wheel.
  16.  
  17.  - Transition Probabilities: The heart of the Markov chain lies in the probabilities
  18.  of transitioning from one state to another. These probabilities form a transition
  19.  matrix, where each element signifies the likelihood of moving between states.
  20.  
  21.  - Transition Matrix: A square matrix where rows and columns correspond to states,
  22.  and each entry represents the probability of transitioning from one state to another.
  23.  In our Roulette context, this matrix captures the dynamics of the game over spins.
  24.  
  25.  - Markov Property: The future state of the system depends only on its current state,
  26.  adhering to the Markov property. The dynamics of the system are memoryless,
  27.  simplifying the modeling of random processes.
  28.  
  29.  Now, armed with the knowledge of Markov chains, let's witness the magic of
  30.  probabilities and state transitions as we simulate the dance of fate on the
  31.  Roulette wheel with this enchanting C program.
  32.  
  33.  INITIAL STATE VECTOR CALCULATION:
  34.  
  35.  Before embarking on our magical journey through the Roulette Markov chain,
  36.  let's decipher the incantation that conjures the initial state vector, v0.
  37.  
  38.  The mystical probabilities for each zone are as follows:
  39.  - Zone A: 1/37 = 0.02702702702
  40.  - Zone B [1-12]: 1/37 * 12 = 0.32432432432
  41.  - Zone C [13-24]: 1/37 * 12 = 0.32432432432
  42.  - Zone D [25-36]: 1/37 * 12 = 0.32432432432
  43.  
  44.  Therefore, the initial state vector v0 is crafted with these probabilities:
  45.  v0 = { 0.02702702702, 0.32432432432, 0.32432432432, 0.32432432432 }
  46.  
  47.  This vector sets the stage for our journey, representing the initial likelihood
  48.  of finding ourselves in each enchanted zone after the first spin of the Roulette wheel.
  49.  
  50.  Now, let the magic unfold as we traverse the Markov chain, weaving the threads
  51.  of destiny and revealing the ever-shifting cosmic energies within the enchanted lands.
  52.  
  53.  THE DARK SPIRIT SCRIPT:
  54.  
  55.  Legend has it that sets A, B, C, and D correspond to specific ranges of numbers
  56.  on the Roulette wheel. Zone A encompasses the single number 0, while zones B, C,
  57.  and D represent ranges [1-12], [13-24], and [25-36], respectively.
  58.  
  59.  Then, the script unfolds as follows:
  60.  
  61.  1. A sample array of mystical symbols is presented, representing the outcome
  62.  of a Roulette game.
  63.  
  64.  2. The `countSpecificTransitions` function takes the mystical sample array and
  65.  counts transitions between sets A, B, C, and D. The ancient spirits are
  66.  summoned to calculate the probabilities of weaving the threads of destiny
  67.  from one set to another.
  68.  
  69.  3. The calculated probabilities are then used to build a powerful transition
  70.  matrix with the `buildTransitionMatrix` function. Each element of the matrix
  71.  represents the likelihood of moving from one enchanted zone to another.
  72.  
  73.  4. The transition matrix is unveiled to mortal eyes through the `printMatrix`
  74.  function, revealing the hidden patterns and cosmic energies.
  75.  
  76.  5. A mystical ritual is performed with the `multiplyMatrixVector` function,
  77.  combining the powers of the sacred matrix and a humble vector. The result is
  78.  a new vector that holds the secrets of transformation, representing the
  79.  probabilities of ending up in each enchanted zone after a Roulette spin.
  80.  
  81.  May the ancient spirits guide you through the script, and may the probabilities
  82.  revealed here bring fortune and wisdom to those who seek the mystical insights
  83.  of the Roulette wheel.
  84.  
  85.  Best of luck on your magical journey! */
  86.  
  87. #include <math.h>
  88. #include <time.h>
  89. #include <stdio.h>
  90. #include <stdlib.h>
  91. #include <stdbool.h>
  92.  
  93. /**
  94.  * @brief Count specific transitions in the sample and calculate transition probabilities.
  95.  *
  96.  * This magical function takes a mystical sample array and counts the transitions between
  97.  * enchanted sets A, B, C, and D. It then summons the ancient spirits to calculate the
  98.  * probabilities of weaving the threads of destiny from one set to another.
  99.  *
  100.  * @param sample The magical sample array containing mystical symbols.
  101.  * @param size The size of the sample array (the length of your magical journey).
  102.  * @param counters The counters representing the cosmic energies of transitions.
  103.  * @param probabilities The probabilities of weaving the threads of destiny between sets.
  104.  */
  105. static void countSpecificTransitions(int sample[], int size, int *counters,
  106. double *probabilities) {
  107. int i, j, k;
  108.  
  109. // Define the sets
  110. int sets[][12] = { { 0 },                                       // A
  111. { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },     // B
  112. { 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }, // C
  113. { 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 }   // D
  114. };
  115.  
  116. // Wipe off counters
  117. for (i = 0; i < 16; i++) {
  118. counters[i] = 0;
  119. probabilities[i] = 0.0;
  120. }
  121.  
  122. // Let's go on a magical journey through the sample array
  123. for (i = 0; i < size - 1; i++) {
  124. int currentSet = -1;
  125. int nextSet = -1;
  126.  
  127. // Seeking the meaning of life in the current set
  128. for (j = 0; j < 4; j++) {
  129. for (k = 0; k < 12; k++) {
  130. /* If our sample number aligns
  131. * with the mystical symbols in the current set */
  132. if (sample[i] == sets[j][k]) {
  133. // We've found it!
  134. currentSet = j;
  135. break;
  136. }
  137. }
  138. /* If we've already found the meaning of life
  139. * there's no need to keep searching */
  140. if (currentSet != -1) {
  141. break;
  142. }
  143. }
  144.  
  145. // Gazing into the crystal ball to find the next set
  146. for (j = 0; j < 4; j++) {
  147. for (k = 0; k < 12; k++) {
  148. if (sample[i + 1] == sets[j][k]) {
  149. nextSet = j;
  150. break;
  151. }
  152. }
  153. if (nextSet != -1) {
  154. break;
  155. }
  156. }
  157.  
  158. // Summoning the ancient spirits to increment the counters
  159. if (currentSet != -1 && nextSet != -1) {
  160. /* We're not just incrementing counters;
  161. * we're weaving the threads of destiny! */
  162. counters[currentSet * 4 + nextSet]++;
  163. }
  164. }
  165.  
  166. // Let's do some magic math
  167. int totalTransitions = size - 1;
  168. for (i = 0; i < 16; i++) {
  169. probabilities[i] = (double) counters[i] / totalTransitions;
  170. }
  171. }
  172.  
  173. /**
  174.  * @brief Build the transition matrix using mystical probabilities.
  175.  *
  176.  * This function takes a set of magical probabilities and weaves them into a powerful
  177.  * transition matrix. Each element of the matrix represents the likelihood of moving
  178.  * from one enchanted zone to another.
  179.  *
  180.  * @param matrix The matrix that will be imbued with magical probabilities.
  181.  * @param probabilities The mystical probabilities, carefully chosen by sorcery.
  182.  */
  183. static void buildTransitionMatrix(double matrix[4][4], double *probabilities) {
  184. /* Fill the matrix with the provided probabilities
  185. * creating a tapestry of transitions */
  186. for (int i = 0; i < 4; i++) {
  187. for (int j = 0; j < 4; j++) {
  188. matrix[i][j] = probabilities[i * 4 + j];
  189. }
  190. }
  191. }
  192.  
  193. /**
  194.  * @brief Normalizes a matrix and tries to make it feel like it fits in.
  195.  *
  196.  * This function takes a matrix and makes each row behave, by subtracting a bit from each element.
  197.  * Think of it as matrix therapy - we're helping them get along better with their row-mates.
  198.  *
  199.  * @param N The size of the matrix.
  200.  * @param matrix The matrix to normalize.
  201.  */
  202. static void normalizeMatrix(int N, double matrix[N][N]) {
  203.    for (int i = 0; i < N; i++) {
  204.        double rowSum = 0.0;
  205.  
  206.        /* Finding the sum of the row
  207.          * - because everyone needs to know their worth! */
  208.        for (int j = 0; j < N; j++) {
  209.            rowSum += matrix[i][j];
  210.        }
  211.  
  212.        /* Subtracting (rowSum - 1) / N from every value in this row
  213.          * - just a little adjustment therapy */
  214.        for (int j = 0; j < N; j++) {
  215.            matrix[i][j] -= (rowSum - 1) / N;
  216.        }
  217.    }
  218. }
  219.  
  220. /**
  221.  * @brief Checks if a matrix is living its best stochastic life.
  222.  *
  223.  * This function takes a matrix and interrogates its rows to see if they're all adding up to 1.
  224.  * It's like a reality show for matrices - if they're not pulling their weight, they're out!
  225.  *
  226.  * @param N The size of the matrix.
  227.  * @param matrix The matrix to investigate.
  228.  * @return Returns true if the matrix is living the stochastic dream, false otherwise.
  229.  */
  230. static bool isStochasticMatrix(int N, double matrix[N][N]) {
  231.    for (int i = 0; i < N; i++) {
  232.        double rowSum = 0.0;
  233.  
  234.        /* Calculating the sum of the current row
  235.          * - because each row is a unique individual */
  236.        for (int j = 0; j < N; j++) {
  237.            rowSum += matrix[i][j];
  238.        }
  239.  
  240.        /* Checking if the sum is approximately equal to 1
  241.          * - because a row that adds up to 1 is a happy row! */
  242.        if (fabs(rowSum - 1.0) > 1e-6) {
  243.            return false;
  244.        }
  245.    }
  246.  
  247.    // The matrix is living its best life!
  248.    return true;
  249. }
  250.  
  251. /**
  252.  * @brief Cast a spell to reveal the mystical matrix.
  253.  *
  254.  * This function is a magical incantation that unleashes the enchanted matrix
  255.  * into the mortal realm. It gracefully prints the ethereal values with precision,
  256.  * allowing mere mortals to catch a glimpse of the hidden patterns.
  257.  *
  258.  * @param matrix The mystical matrix to be unveiled.
  259.  */
  260. static void printMatrix(double matrix[4][4]) {
  261. for (int i = 0; i < 4; i++) {
  262. for (int j = 0; j < 4; j++) {
  263. // Reveal the magical values with four decimal places
  264. printf("%.4f ", matrix[i][j]);
  265. }
  266. // Move to the next line, as the magic unfolds row by row
  267. printf("\n");
  268. }
  269. }
  270.  
  271. /**
  272.  * @brief Unleash the magic of matrix-vector multiplication.
  273.  *
  274.  * This function is a mystical ritual that combines the powers of a sacred matrix
  275.  * and a humble vector. It gracefully performs the multiplication, weaving the
  276.  * threads of destiny to produce a new vector that holds the secrets of transformation.
  277.  *
  278.  * @param matrix The sacred matrix, carefully crafted by the wizards of computation.
  279.  * @param inputVector The humble vector offering itself to the magic of multiplication.
  280.  * @param resultVector The newborn vector, now imbued with the enchanted transformation.
  281.  */
  282. static void multiplyMatrixVector(double matrix[4][4], double *inputVector,
  283. double *resultVector) {
  284. for (int i = 0; i < 4; i++) {
  285. // Prepare the newborn vector, clearing any remnants of previous enchantments
  286. resultVector[i] = 0.0;
  287. for (int j = 0; j < 4; j++) {
  288. // Unleash the magic: combine the powers of matrix and vector
  289. resultVector[i] += matrix[i][j] * inputVector[j];
  290. }
  291. }
  292. }
  293.  
  294. /**
  295.  * @brief Normalizes a vector and makes its elements feel like they're on a diet.
  296.  *
  297.  * This magical function takes a vector on a sumptuous feast and says, "Enough is enough!"
  298.  * It calculates the sum of the elements, scolds them for overindulgence, and puts them on
  299.  * a strict diet by dividing each element by the sum. Now, the vector is light, fit, and ready
  300.  * for the runway – or any mathematical adventure!
  301.  *
  302.  * @param vector The vector to be normalized, because even vectors need to watch their weight.
  303.  * @param size The size of the vector – because size matters, especially in the world of vectors.
  304.  */
  305. void normalizeVector(double *vector, int size) {
  306.    double sum = 0.0;
  307.  
  308.    // Calculate the sum of the elements – a grand feast awaits!
  309.    for (int i = 0; i < size; i++) {
  310.        sum += vector[i];
  311.    }
  312.  
  313.    // Normalize by dividing each element by the sum of the elements
  314.    for (int i = 0; i < size; i++) {
  315.        vector[i] /= sum;
  316.    }
  317. }
  318.  
  319.  
  320. /**
  321.  * @brief Generates a random list of numbers to keep life exciting.
  322.  *
  323.  * This function is your go-to party planner for creating a list that's as unpredictable as life itself.
  324.  * It seeds the random number generator with the current time, ensuring a unique and lively mix every time.
  325.  *
  326.  * @param list The list to be filled with random numbers.
  327.  * @param size The size of the list - because size matters, especially in random number lists.
  328.  */
  329. static void generateRandomList(int *list, int size) {
  330.    // Let's throw a dice and see where the randomness takes us!
  331.    srand((unsigned int) time(NULL));
  332.  
  333.    // Generating random numbers and filling the list with excitement
  334.    for (int i = 0; i < size; i++) {
  335.       /* Generating a random number between 0 and 36
  336.         * - because variety is the spice of life! */
  337.     list[i] = rand() % 37;
  338.    }
  339. }
  340.  
  341. /**
  342.  * @brief Embark on a magical journey through the enchanted realms of sets A, B, C, and D.
  343.  *
  344.  * This mystical main function leads a daring expedition into the unseen world of transitions
  345.  * and probabilities. A sample array of mystical symbols is presented to the ancient wizards
  346.  * who count specific transitions, unveil the secrets of probability, and build a powerful
  347.  * transition matrix. The enchanted matrix is then used to transform an initial state vector
  348.  * into a new state, revealing the ever-shifting cosmic energies within the enchanted lands.
  349.  *
  350.  * @return The triumphant return code, signifying the successful completion of the magical journey.
  351.  */
  352. int main() {
  353.    // Sample array
  354.    int initialData[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 };
  355.    int size = (int)sizeof(initialData) / sizeof(initialData[0]);
  356.  
  357.    // Declare and allocate memory for the sample array
  358.    int *sample = (int *)malloc(size * sizeof(int));
  359.  
  360.    // Check if memory allocation was successful
  361.    if (sample == NULL) {
  362.        fprintf(stderr, "Memory allocation failed :(\n");
  363.        return 1; // Return an error code
  364.    }
  365.  
  366.    // Initialize sample array with default values
  367.    for (int i = 0; i < size; i++) {
  368.        sample[i] = i;
  369.    }
  370.  
  371.    // Initialize counters and probabilities
  372.    int counters[16];
  373.    double probabilities[16];
  374.  
  375.    int i = 0;
  376.    int winningBet = 0;
  377.  
  378.    do {
  379.        // Count specific transitions
  380.        countSpecificTransitions(sample, size, counters, probabilities);
  381.  
  382.        // Print the results
  383.        printf("\n");
  384.        for (i = 0; i < 16; i++) {
  385.            char currentSet = (char)('A' + i / 4);
  386.            char nextSet = (char)('A' + i % 4);
  387.  
  388.            printf("Transition %c->%c: %d, Probability: %.4f\n", currentSet, nextSet, counters[i], probabilities[i]);
  389.        }
  390.  
  391.        // Build the transition matrix
  392.        double transitionMatrix[4][4];
  393.        buildTransitionMatrix(transitionMatrix, probabilities);
  394.        if (!isStochasticMatrix(4, transitionMatrix)) {
  395.            normalizeMatrix(4, transitionMatrix);
  396.        }
  397.  
  398.        // Print the transition matrix
  399.        printf("\nTransition Matrix:\n");
  400.        printMatrix(transitionMatrix);
  401.  
  402.        // Build the new state vector
  403.        double initialState[4] = {0.02702702702, 0.32432432432, 0.32432432432, 0.32432432432};
  404.        double newState[4];
  405.        multiplyMatrixVector(transitionMatrix, initialState, newState);
  406.  
  407.        // Normalize the new state vector
  408.        normalizeVector(newState, 4);
  409.  
  410.        // Print the new state vector with corresponding zones and intervals
  411.        printf("\nNew state vector:\n");
  412.        for (i = 0; i < 4; i++) {
  413.            char zoneLabel;
  414.            const char *intervalDescription;
  415.  
  416.            // Determine the zone label and interval description
  417.            switch (i) {
  418.            case 0:
  419.                zoneLabel = 'A';
  420.                intervalDescription = "Only 0 ";
  421.                break;
  422.            case 1:
  423.                zoneLabel = 'B';
  424.                intervalDescription = "[1-12] ";
  425.                break;
  426.            case 2:
  427.                zoneLabel = 'C';
  428.                intervalDescription = "[13-24]";
  429.                break;
  430.            case 3:
  431.                zoneLabel = 'D';
  432.                intervalDescription = "[25-36]";
  433.                break;
  434.            default:
  435.                // Handle an unexpected index (this should not happen)
  436.                zoneLabel = '?';
  437.                intervalDescription = "Unknown Interval";
  438.                break;
  439.            }
  440.  
  441.            // Print the probability along with zone and interval information
  442.            printf("Zone %c %s -> %.3f%%\n", zoneLabel, intervalDescription, (double)newState[i] * 100);
  443.        }
  444.  
  445.        printf("\nEnter a new winningBet (or any non-integer to exit): ");
  446.        if (scanf("%d", &winningBet) != 1) {
  447.            break;
  448.        }
  449.  
  450.        // Update the sample array with the new winningBet
  451.        // (For simplicity, just add the winningBet to the end of the array
  452.        sample = realloc(sample, (size + 1) * sizeof(int));
  453.        if (sample == NULL) {
  454.            fprintf(stderr, "Memory reallocation failed :(\n");
  455.            return 1; // Return an error code
  456.        }
  457.        sample[size] = winningBet;
  458.        size++;
  459.  
  460.    } while (1);
  461.  
  462.    // Free the allocated memory
  463.    free(sample);
  464.  
  465.    // The triumphant return code!
  466.    return 0;
  467. }
  468.  



portal foto
3  Programación / Scripting / Git Update Manager en Batch en: 20 Noviembre 2023, 23:02 pm
¡Hola comunidad!

Hoy quiero compartir con vosotros un script batch que he creado para simplificar el proceso de actualización de repositorios Git. Este script es especialmente útil si trabajas con varios proyectos y deseas agilizar la tarea de actualizar y sincronizar con un repositorio remoto.

Aquí un resumen de su funcionalidad:

1. Validación de parámetros y dependencias, asegurándose de que Git esté instalado.

2. Configuración de variables, incluyendo rutas de directorios y configuraciones generales.

3. Configuración de banderas para determinar la acción a realizar (actualización o mostrar ayuda).

4. Selección del proyecto a actualizar o mostrar la ayuda según el parámetro proporcionado.

5. Mostrar la ayuda si se solicita mediante el parámetro -h.

6. Actualización del proyecto seleccionado:

    a. Búsqueda del archivo ZIP más reciente en el directorio de proyectos.
    b. Obtención de la fecha y hora actuales para crear un nuevo branch en Git.
    c. Limpieza del directorio de destino, conservando el directorio .git.
    d. Descompresión del último archivo ZIP en el directorio de destino.
    e. Setup de Git y push de cambios al repositorio remoto.

Nota: Este script incluye tres opciones de ejemplo por defecto (-p1, -p2, -p3) para mostrar su funcionalidad. Estas opciones representan proyectos ficticios y repositorios de ejemplo. Estas opciones pueden ser personalizadas o expandidas según las necesidades específicas del usuario. Simplemente modifica las secciones correspondientes del script para reflejar tus proyectos y repositorios reales.

Nota: Este script sigue una aproximación de almacenamiento que guarda copias completas del proyecto con cada commit en lugar de almacenar cambios incrementales (diffs). La elección de almacenar copias completas puede resultar en un mayor uso de espacio en comparación con la técnica tradicional de Git, que almacena solo las diferencias entre commits. Sin embargo, esta estrategia se ha adoptado aquí para simplificar la gestión y garantizar que cada respaldo sea un punto coherente y completamente funcional en el tiempo.

Nota: La gestión de Git en este script puede no seguir las prácticas más ortodoxas, pero está diseñada para simplificar el proceso de realizar backups periódicos de proyectos en la nube. En lugar de utilizar ramas separadas para cada actualización, se utiliza la fecha y hora actual como parte del nombre de la rama, lo que puede no ser la convención típica de Git. La eliminación y recreación del directorio de destino puede ser considerada una aproximación inusual, pero se ha implementado para garantizar una limpieza completa antes de extraer el último respaldo.

En definitiva, este script es una solución práctica para aquellos que buscan una forma rápida y automatizada de mantener respaldos actualizados en un repositorio remoto, aunque puede no seguir las mejores prácticas recomendadas por la comunidad Git.

Código:
@echo off
setlocal enabledelayedexpansion

REM Batch Script for Git Project Update
REM Author: profinet
REM Date: 2023-11-20
REM Version: 0.1

REM Description:
REM This batch script is designed to automate the process of updating Git projects.
REM It includes functionality for handling multiple projects, cleaning the destination directory, extracting the latest backup, and pushing changes to the remote repository.
REM The script is intended to streamline the update process and reduce manual intervention.

REM Author's Note:
REM The script was created by profinet on the specified date. For any inquiries or suggestions, please contact the author.

REM Version History:
REM - Version 0.1 (2023-11-20): Initial release of the script.
REM   This version includes basic functionality for updating Git projects and serves as the foundation for future enhancements.

REM Check for provided input
if "%~1"=="" (
    echo No parameters provided. Exiting...
    exit /b
)

set "validParams=-p1 -p2 -p3 -h"
if "!validParams:%~1=!" equ "%validParams%" (
    echo Invalid parameter: %1
    echo Valid parameters are: %validParams%
    exit /b
)

REM Check for dependencies
set "gitFolder=%ProgramFiles%\Git"
if not exist "%gitFolder%" (
    set "gitFolder=%ProgramFiles(x86)%\Git"
    if not exist "%gitFolder%" (
        echo Git is not installed in the default location. Exiting...
        exit /b
    )
)

REM Create environment variable to use git commands
set "PATH=%PATH%;%gitFolder%\cmd"

REM Set up general variables
set "latestFile="
set "projectDirFrom=C:\Path\To\Your\Projects"
set "projectDirTo=C:\Path\To\Your\Git\Repos"

REM Set up flags
set "updateProject=false"
set "showHelp=false"

REM Read which option was selected
if "%~1" == "-p1" (
    set "updateProject=true"
    set "projectFolder=Project1"
    set "repo_uri=https://git.example.com/your_username/project1.git"
)
if "%~1" == "-p2" (
    set "updateProject=true"
    set "projectFolder=Project2"
    set "repo_uri=https://git.example.com/your_username/project2.git"
)
if "%~1" == "-p3" (
    set "updateProject=true"
    set "projectFolder=Project3"
    set "repo_uri=https://git.example.com/your_username/project3.git"
)
if "%~1" == "-h" set "showHelp=true"

REM Add as many options as needed
:showHelp
if "%showHelp%"=="true" (
    echo Use of script:
    echo   %~nx0 -p1  Update Project1
    echo   %~nx0 -p2  Update Project2
    echo   %~nx0 -p3  Update Project3
    echo   %~nx0 -h   Show help
    exit /b
)

REM Look up the latest backups
if "%updateProject%"=="true" (
    cd "%projectDirFrom%\%projectFolder%\"
    for %%i in (*.zip) do (
        set "currentFile=%%i"
        if "!currentFile!" gtr "!latestFile!" (
            set "latestFile=!currentFile!"
        )
    )

    REM Get date and time to rename the new branch
    set "current_date=!date:/=-!!time::=-!"
    set dt=%DATE:~6,4%_%DATE:~3,2%_%DATE:~0,2%__%TIME:~0,2%_%TIME:~3,2%_%TIME:~6,2%
    set dt=%dt: =0%

    if "%updateProject%"=="true" (
        cd /d "%projectDirTo%\%projectFolder%"

        REM Delete all files (excluding .git) in the destination directory
        for %%i in (*) do (
            if /i not "%%i"=="%projectDirTo%\%projectFolder%\.git" (
                del "%%i"
            )
        )

        REM Delete all subdirectories (excluding .git) in the destination directory
        for /d %%i in (*) do (
            if /i not "%%i"=="%projectDirTo%\%projectFolder%\.git" (
                rmdir /s /q "%%i"
            )
        )

        REM Extract the latest zip file to the destination directory
        powershell -command Expand-Archive -Path '%projectDirFrom%\%projectFolder%\!latestFile!' -DestinationPath '%projectDirTo%\%projectFolder%' -Force

        REM Set up Git and push the changes
        git remote add origin %repo_uri%
        git checkout -b %dt%
        cd %projectFolder%
        git add --all
        git commit -m "Update %dt%"
        git push -u origin %dt%
    )
)

echo.
pause > nul
endlocal
4  Programación / Programación C/C++ / Librería alloc -- asignación dinámica de memoria en Arduino en: 16 Noviembre 2023, 22:25 pm
¿Qué es la asignación dinámica de memoria?

Es la solicitud de un programa para reservar un bloque de memoria en tiempo de ejecución. Se consigue a través de las funciones malloc() y free() en C/C++. No obstante, en sistemas embebidos como los microcontroladores, este recurso de la programación puede derivar en problemas graves.

* Limitación de recursos: los MCUs no comparten las mismas característicias en el hardware que los ordenadores de uso personal, son menos potentes.

* Fragmentación de la memoria: la asignación y liberación repetida de bloques de memoria conduce a problemas de fragmentación, lo que dificulta la asignación de bloques contiguos.

* Predictibilidad: la gestión dinámica de la memoria puede hacer que el programa sea menos predecible, lo cual es especialmente crítico en sistemas embebidos; ya que afecta directamente al tiempo de respuesta de los recursos compartidos.

¿Cómo se divide la memoria en un programa?

Durante el proceso de compilación, se traduce el código fuente a código máquina y se genera los archivos objeto que contienen información sobre el código y los datos. Posteriormente, los archivos objeto se combinan (gracias al enlazador) para formar un programa ejecutable. En esta fase, se asignan direcciones de memoria a las diferentes secciones de memoria que resuelven las referencias a símbolos entre los distintos ficheros objeto.

Las secciones de memoria son:

* .TEXT: contiene el código máquina de las instrucciones del programa. Esta sección es de sólo lectura y ejecución.

* .DATA: almacena datos inicializados, como variables globales o estáticas, constantes, etc.

* .BSS: almacena datos no inicializados, es decir, durante el enlazado se reserva un espacio determinado para estas variables.

Ahora bien, existen otras dos áreas de memoria utilizadas durante la ejecución de un programa.

* Heap: es una región destinada a la asignación dinámica de memoria, por lo general, de estructuras de datos grandes, como instancias o matrices.

* Stack: es la región de memoria empleada para almacenar las variables locales y registros de activación de funciones. Funciona como una FIFO (First In First Out).

¿Y qué tiene que ver todo ésto?

El stack y el heap comparten los mismos recursos de memoria física, de manera que pueden ser limitantes y muy problemáticos si el programador no tiene cuidado. Habitualmente el S.O. ya se encarga de arbitrar el uso entre estas dos regiones, de modo que lo que no suele ser un problema en el diseño de software para computadoras, se vuelve toda una odisea en microcontroladores.

Yo he desarrollado una pequeña librería para facilitar la asignación dinámica de memoria en sistemas embebidos, como el microcontrolador Atmega328 (comúnmente conocido como "Arduino"); aunque también ha sido testada en un microcontrolador de Renesas R6T1, con unos cambios mínimos y evidentes en la directivas a los encabezados de las bibliotecas. Mi librería alloc se basa en la reserva estática de memoria en el segmento .BSS, haciendo uso de un memory pool personalizado.

¡A continuación os comparto el código! Espero que os guste.  ;)

Encabezado

Código:
/**
 * Author:     profinet
 * Date:       November 14, 2023
 * Version:    v0.1
 *
 * @file alloc.h
 * @brief Memory allocation library for Arduino.
 *
 * This library provides a memory allocation manager for Arduino projects,
 * allowing efficient allocation and deallocation of memory from a predefined
 * memory pool. The memory pool is divided into fixed-size blocks, and the
 * library supports allocation of contiguous blocks for larger memory needs.
 *
 * Usage:
 * 1. Include the library in your Arduino sketch: #include "alloc.h"
 * 2. Create an instance of the alloclib class: alloclib myMemoryAllocator;
 * 3. Use the alloc and dealloc methods to manage memory dynamically.
 *
 * Note: This library is designed for projects where dynamic memory
 * allocation is required, and it may not be suitable for all applications.
 */

#ifndef ALLOC_H
#define ALLOC_H

#include <Arduino.h>

/* Define the size of the memory pool and the block size */
#define MEMORY_POOL_SIZE 1024
#define BLOCK_SIZE 32

// Define a structure to represent a block of memory
struct MemoryBlock {
int size;
uint8_t *data;
};

class alloclib {
public:

alloclib() {
init();
}
~alloclib() {
}

void* alloc(uint16_t size);
void dealloc(void *ptr, uint16_t size);

template<typename T>
T* alloc(int count = 1);

template<typename T>
void dealloc(T *ptr, int count = 1);

private:

void init();
void* allocFromPool(int16_t size);
void deallocFromPool(void *ptr, uint16_t size);

MemoryBlock blocks[MEMORY_POOL_SIZE / BLOCK_SIZE];
uint8_t memoryPool[MEMORY_POOL_SIZE];
};

/**
 * @brief Allocates an array of elements of type T from the memory pool.
 *
 * This templated function allocates memory for an array of elements of type T
 * from the memory pool.
 *
 * It calculates the required size based on the count of
 * elements and checks for potential overflow. If the allocation is successful,
 * it returns a pointer to the allocated memory; otherwise, it returns nullptr.
 *
 * @tparam T The type of elements in the array.
 * @param count The number of elements to allocate.
 * @return A pointer to the allocated array, or nullptr if allocation fails.
 */
template<typename T>
T* alloclib::alloc(int count) {
size_t sizeRequired = static_cast<size_t>(count) * sizeof(T);

// Check for potential overflow
if (sizeRequired > MEMORY_POOL_SIZE) {
/* TODO: Handle the error or report it in a way that makes sense for your application */
// Return nullptr to indicate allocation failure
return nullptr;
} else {
// Perform the allocation
return static_cast<T*>(allocFromPool(
static_cast<uint16_t>(sizeRequired)));
}
}

/**
 * @brief Deallocates an array of elements of type T back to the memory pool.
 *
 * This templated function deallocates memory for an array of elements of type T
 * previously allocated from the memory pool.
 *
 * It calculates the required size
 * based on the count of elements and checks for potential overflow. If the
 * deallocation is successful, it updates the memory pool; otherwise, it may
 * handle the error or report it in a way that makes sense for your application.
 *
 * @tparam T The type of elements in the array.
 * @param ptr A pointer to the array to deallocate.
 * @param count The number of elements in the array.
 */
template<typename T>
void alloclib::dealloc(T *ptr, int count) {
size_t sizeRequired = static_cast<size_t>(count) * sizeof(T);

// Check for potential overflow
if (sizeRequired > MEMORY_POOL_SIZE) {
/* TODO: Handle the error or report it in a way that makes sense for your application */
} else {
// Perform the deallocation
deallocFromPool(ptr, static_cast<uint16_t>(sizeRequired));
}
}

#endif  // ALLOC_H

Archivo de implementación

Código:
/**
 * Author:     profinet
 * Date:       November 14, 2023
 * Version:    v0.1
 *
 * @file alloc.h
 * @brief Memory allocation library for Arduino.
 *
 * This library provides a memory allocation manager for Arduino projects,
 * allowing efficient allocation and deallocation of memory from a predefined
 * memory pool. The memory pool is divided into fixed-size blocks, and the
 * library supports allocation of contiguous blocks for larger memory needs.
 *
 * Usage:
 * 1. Include the library in your Arduino sketch: #include "alloc.h"
 * 2. Create an instance of the alloclib class: alloclib myMemoryAllocator;
 * 3. Use the alloc and dealloc methods to manage memory dynamically.
 *
 * Note: This library is designed for projects where dynamic memory
 * allocation is required, and it may not be suitable for all applications.
 */

#include <Arduino.h>
#include "alloc.h"

/**
 * @brief Initializes the memory pool with contiguous blocks of memory.
 *
 * This function initializes the memory pool by dividing it into contiguous
 * blocks of fixed size. It sets up the initial state of each block, including
 * its size and data pointer, based on the predefined block size and the size
 * of the memory pool.
 */
void alloclib::init() {
for (int i = 0; i < MEMORY_POOL_SIZE / BLOCK_SIZE; ++i) {
blocks[i].size = BLOCK_SIZE;
blocks[i].data = &memoryPool[i * BLOCK_SIZE];
}
}

/**
 * @brief Allocates a block of memory from the memory pool.
 *
 * This function attempts to allocate a block of memory of the specified size
 * from the memory pool. It first checks for contiguous blocks to satisfy the
 * request efficiently.
 *
 * If the requested size is greater than one block, it
 * searches for a sequence of contiguous blocks. If found, it allocates the
 * memory and returns a pointer to the allocated block.
 *
 * If the requested size is within a single block, it looks for a block with sufficient free space.
 * If found, it allocates the memory and returns a pointer to the allocated
 * block. If no suitable block is found, it returns nullptr.
 *
 * @param size The size of the memory block to allocate.
 * @return A pointer to the allocated memory block, or nullptr if allocation fails.
 */
void* alloclib::allocFromPool(int16_t size) {
if (size > 0) {
int blocksNeeded = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
if (blocksNeeded > 1) {
// Iterate through the memory pool to find a sequence of contiguous blocks
for (int i = 0; i < MEMORY_POOL_SIZE / BLOCK_SIZE; ++i) {
int contiguousBlocks = 0;

// Check for contiguous blocks with sizes >= BLOCK_SIZE
while (i + contiguousBlocks < MEMORY_POOL_SIZE / BLOCK_SIZE
&& blocks[i + contiguousBlocks].size >= BLOCK_SIZE) {
contiguousBlocks++;
if (contiguousBlocks == blocksNeeded) {
break;
}
}

if (contiguousBlocks == blocksNeeded) {
void *ptr = blocks[i].data;

// Mark the blocks as allocated (size = 0)
for (int j = 0; j < contiguousBlocks; ++j) {
blocks[i + j].size = 0;

// Update data pointers for subsequent blocks
if (j < contiguousBlocks - 1) {
blocks[i + j + 1].data = blocks[i + j].data +
BLOCK_SIZE;
}
}

// Return the pointer to the allocated memory
return ptr;
}
}
return nullptr;
}

// If the requested size is within one block
for (int i = 0; i < MEMORY_POOL_SIZE / BLOCK_SIZE; ++i) {
if (blocks[i].size >= size) {
void *ptr = blocks[i].data;

// Update the size and data pointer for the allocated block
blocks[i].size -= size;
blocks[i].data += size;
return ptr;
}
}
}
return nullptr; // Not enough free space
}

/**
 * @brief Deallocates a block of memory back to the memory pool.
 *
 * This function deallocates a block of memory previously allocated from the
 * memory pool. It takes a pointer to the memory block and its size as
 * parameters.
 *
 * The function searches for the corresponding block in the memory
 * pool based on the provided pointer. It updates the size of the block and
 * coalesces adjacent free blocks if applicable.
 *
 * @param ptr A pointer to the memory block to deallocate.
 * @param size The size of the memory block to deallocate.
 */
void alloclib::deallocFromPool(void *ptr, uint16_t size) {
if (ptr != nullptr && size > 0) {
for (int i = 0; i < MEMORY_POOL_SIZE / BLOCK_SIZE; ++i) {

// Check if the pointer is within the range of the current block
if (ptr >= blocks[i].data && ptr < blocks[i].data + BLOCK_SIZE) {
// Increase the size of the block by the deallocated size
blocks[i].size += size;

// Check if there is a next block and it is also free
if (i < MEMORY_POOL_SIZE / BLOCK_SIZE - 1
&& blocks[i + 1].size > 0) {
if (blocks[i].data + BLOCK_SIZE == blocks[i + 1].data) {
// Merge the current block with the next block
blocks[i].size += blocks[i + 1].size;
blocks[i + 1].size = 0;
}
}
return;
}
}
}
}

Ejemplo de uso en Arduino

Código:
#include "alloc.h"

alloclib allc;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int size = 10;

  // Allocate and print intArray
  int* intArray = allc.alloc<int>(size);
  if (intArray != nullptr) {
    for (size_t i = 0; i < size; i++) {
      intArray[i] = i * 2;
      Serial.print(intArray[i]);
      Serial.print(" ");
    }
    Serial.println();  // Move to the next line
  }
  allc.dealloc(intArray, size);
  delay(1000);

  // Allocate and print doubleArray
  double* doubleArray = allc.alloc<double>(size);
  if (doubleArray != nullptr) {
    for (size_t i = 0; i < size; i++) {
      doubleArray[i] = i * 1.5;
      Serial.print(doubleArray[i]);
      Serial.print(" ");
    }
    Serial.println();  // Move to the next line
  }
  allc.dealloc(doubleArray, size);
  delay(1000);

  // Allocate and print charArray
  char* charArray = allc.alloc<char>(size);
  if (charArray != nullptr) {
    charArray[0] = 'h';
    charArray[1] = 'e';
    charArray[2] = 'l';
    charArray[3] = 'l';
    charArray[4] = 'o';
    charArray[5] = '\0';  // Null terminator to make it a valid C-string

    Serial.print(charArray);
    Serial.println();  // Move to the next line
  }
  allc.dealloc(charArray, size);
  delay(1000);
}
Páginas: [1]
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines