Làm thế nào để tạo ngẫu nhiên của anyfile?


9

Chúng ta đều biết ngẫu nhiên ASCII được tạo bởi ssh-keygenkhi tạo hoặc xác thực sshcác khóa công khai.

Chúng tôi cũng biết bạn có thể tạo băm của bất kỳ tệp nào có sha1sumhoặc md5sum.

Nhưng, có thể tạo ngẫu nhiên "ssh-keygen-style" từ bất kỳ tệp nào không phải là khóa ssh công khai không?

Đó sẽ là một cách thú vị hơn để so sánh trực quan tổng kiểm tra của hai tệp.

Câu trả lời:


8

Bạn có thể tạo nghệ thuật ngẫu nhiên của bất kỳ tệp nào với chương trình C nhỏ này được tạo bởi nirejan :

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

#define XLIM 17
#define YLIM 9
#define ARSZ (XLIM * YLIM)

#define DEBUG 0

static uint16_t array[ARSZ];

const char symbols[] = {
    ' ', '.', 'o', '+',
    '=', '*', 'B', 'O',
    'X', '@', '%', '&',
    '#', '/', '^', 'S', 'E'
};

void print_graph(void)
{
    uint8_t i;
    uint8_t j;
    uint16_t temp;

    printf("+--[ RandomArt ]--+\n");

    for (i = 0; i < YLIM; i++) {
        printf("|");
        for (j = 0; j < XLIM; j++) {
            temp = array[j + XLIM * i];
            printf("%c", symbols[temp]);
        }
        printf("|\n");
    }

    printf("+-----------------+\n");
}

static char string[256];

static int ishex (char c)
{
    if ((c >= '0' && c <= '9') ||
        (c >= 'A' && c <= 'F') ||
        (c >= 'a' && c <= 'f')) {
            return 1;
    }

    return 0;
}

/*
 * The hexval function expects a hexadecimal character in the range
 * [0-9], [A-F] or [a-f]. Passing any other character will result in
 * undefined behaviour. Make sure you validate the character first.
 */
static uint8_t hexval (char c)
{
    if (c <= '9') {
        return (c - '0');
    } else if (c <= 'F') {
        return (c - 'A' + 10);
    } else if (c <= 'f') {
        return (c - 'a' + 10);
    }

    return 0;
}

int convert_string(char *arg)
{
    uint16_t i;
    char c;

    i = 0;
    while (*arg && i < 255) {
        c = *arg;
        if (!ishex(c)) {
            printf("Unrecognized character '%c'\n", c);
            return 1;
        }
        arg++;

        string[i] = hexval(c) << 4;

        if (!*arg) {
            printf("Odd number of characters\n");
            return 1;
        }
        c = *arg;

        if (!ishex(c)) {
            printf("Unrecognized character '%c'\n", c);
            return 1;
        }
        arg++;

        string[i] |= hexval(c);
        i++;
    }

    // Add the terminating null byte
    string[i] = '\0';
    return 0;
}

uint8_t new_position(uint8_t *pos, uint8_t direction)
{
    uint8_t newpos;
    uint8_t upd = 1;
    int8_t x0;
    int8_t y0;
    int8_t x1;
    int8_t y1;

    x0 = *pos % XLIM;
    y0 = *pos / XLIM;

    #if DEBUG
    printf("At position (%2d, %2d)... ", x0, y0);
    #endif

    switch (direction) {
        case 0: // NW
            #if DEBUG
            printf("Moving NW... ");
            #endif
            x1 = x0 - 1;
            y1 = y0 - 1;
            break;
        case 1: // NE
            #if DEBUG
            printf("Moving NE... ");
            #endif
            x1 = x0 + 1;
            y1 = y0 - 1;
            break;
        case 2: // SW
            #if DEBUG
            printf("Moving SW... ");
            #endif
            x1 = x0 - 1;
            y1 = y0 + 1;
            break;
        case 3: // SE
            #if DEBUG
            printf("Moving SE... ");
            #endif
            x1 = x0 + 1;
            y1 = y0 + 1;
            break;
        default: // Should never happen
            #if DEBUG
            printf("INVALID DIRECTION %d!!!", direction);
            #endif
            x1 = x0;
            y1 = y0;
            break;
    }

    // Limit the range of x1 & y1
    if (x1 < 0) {
        x1 = 0;
    } else if (x1 >= XLIM) {
        x1 = XLIM - 1;
    }

    if (y1 < 0) {
        y1 = 0;
    } else if (y1 >= YLIM) {
        y1 = YLIM - 1;
    }

    newpos = y1 * XLIM + x1;
    #if DEBUG
    printf("New position (%2d, %2d)... ", x1, y1);
    #endif

    if (newpos == *pos) {
        #if DEBUG
        printf("NO CHANGE");
        #endif

        upd = 0;
    } else {
        *pos = newpos;
    }

    #if DEBUG
    printf("\n");
    #endif

    return upd;
}

void drunken_walk(void)
{
    uint8_t pos;
    uint8_t upd;
    uint16_t idx;
    uint8_t i;
    uint8_t temp;

    pos = 76;
    for (idx = 0; string[idx]; idx++) {
        temp = string[idx];

        #if DEBUG
        printf("Walking character index %d ('%02x')...\n", idx, temp);
        #endif

        for (i = 0; i < 4; i++) {
            upd = new_position(&pos, temp & 3);
            if (upd) {
                array[pos]++;
            }
            temp >>= 2;
        }
    }

    array[pos] = 16; // End
    array[76] = 15; // Start
}

int main(int argc, char *argv[])
{
    if (argc != 2) {
        printf("Usage: bishop <hex string>\n");
        return 1;
    }

    if (convert_string(argv[1])) {
        printf("String conversion failed!\n");
        return 1;
    }

    drunken_walk();
    print_graph();

    return 0;
}

Để sử dụng nó, hãy làm theo các bước sau:

  1. Đặt mã nguồn vào một tệp:
    • Mở gedit hoặc trình soạn thảo văn bản yêu thích của bạn.
    • Dán mã nguồn ở trên.
    • Lưu nó như bishop.c.
  2. Biên dịch mã đang chạy gcc bishop.c -o bishop.
  3. Xem nghệ thuật ngẫu nhiên của bất kỳ tệp nào (tệp này ở đâu myfile):

    ./bishop $(sha512sum myfile | cut -f1 -d ' ')
    
  4. Tạo một tập lệnh tùy chỉnh để xem nghệ thuật ngẫu nhiên của bất kỳ tệp nào:

    • Tạo thư mục nhị phân cục bộ nếu không tồn tại:

      sudo mkdir -p /usr/local/bin
      
    • Tạo một tệp trên thư mục đó với tập lệnh:

      sudo touch /usr/local/bin/randomart
      
    • Cấp quyền cho tệp:

      sudo chmod 777 /usr/local/bin/randomart
      
    • Chạy gedit /usr/local/bin/randomartđể chỉnh sửa tập tin và dán nó vào nó:

      #!/bin/bash
      
      bishop $(sha512sum "$@" | cut -f1 -d ' ')
      
    • Lưu các tập tin.

    • Sao chép chương trình mà chúng tôi đã xây dựng ở bước trước vào thư mục nhị phân cục bộ:

      sudo cp bishop /usr/local/bin/
      
    • Cấp quyền chạy cho nhị phân:

      sudo chmod a+x /usr/local/bin/bishop
      
  5. Sử dụng chương trình mới được tạo đang chạy randomart myfileở đâu myfilelà tập tin.


1
Rất ấn tượng
AB

2

Trang OpenSSH Keys và The Drunken Bishop giới thiệu tốt về cách thức hoạt động của thuật toán.

Các chi tiết của nó có thể được tìm thấy trong
Giám mục say rượu: Một phân tích về thuật toán hình ảnh vân tay OpenSSH .

Chủ đề được thảo luận dưới dạng tổng quát hơn trong bài báo
"Trực quan hóa Hash: Kỹ thuật mới để cải thiện an ninh thế giới thực", Perrig A. và Song D., 1999, Hội thảo quốc tế về kỹ thuật mã hóa và thương mại điện tử (CrypTEC '99 ) " .


Tôi có thể tạo tổng kiểm MD5 của bất kỳ tệp nào không phải là khóa ssh công khai, chẳng hạn như tệp JPG. Làm cách nào tôi có thể nhận được ngẫu nhiên của MD5 đó?
Tulains Córdova

+10: Bạn đã cho tôi điểm bắt đầu. ;-)
Helio
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.