| Deutsch English Français Italiano |
|
<640286bde8850f22227e92c0156e382704f6e916@i2pn2.org> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!eternal-september.org!feeder3.eternal-september.org!i2pn.org!i2pn2.org!.POSTED!not-for-mail
From: Stefan Claas <fgrsna.pynnf@vagrearg.eh>
Newsgroups: sci.crypt
Subject: Putting encrypted data in an X-Face Header :-)
Date: Sat, 22 Mar 2025 12:53:51 +0100
Organization: i2pn2 (i2pn.org)
Message-ID: <640286bde8850f22227e92c0156e382704f6e916@i2pn2.org>
MIME-Version: 1.0
Injection-Date: Sat, 22 Mar 2025 11:53:51 -0000 (UTC)
Injection-Info: i2pn2.org;
logging-data="1265485"; mail-complaints-to="usenet@i2pn2.org";
posting-account="ieSrCjSDShpZNyqIW52mlwIkg76Hsp+TOOO6KTdfCN8";
User-Agent: flnews/1.3.0pre29 (for GNU/Linux)
Cancel-Lock: sha1:rQ/6hLTGFpAi3+hXRuoDW+cW+SE=
X-Date: It's Sat Sep 11526 12:53:51 PM CET 1993, the September that never ends.
X-Spam-Checker-Version: SpamAssassin 4.0.0
X-Ed25519-Sig: 42eb9641913c28a5c063925bd9dbf0b8d24c34701d01489fb8ed5d9b8f0a60e7
f68d0b93e306a720b0d66263ffc6374c4b0950b8d7d77357272ef5844f0adf0a
X-Ed25519-Pub: c0ffee5a36e581eb10f60b2831b3cdb955d2e7ef680dd282a8d43ad8b84b357a
Bytes: 7449
Lines: 185
Hi all,
just for fun. You can put up to 288 bytes in an X-Face header. If the
message is shorter than 288 bytes it will be padded with a checkerboard
pattern.
https://www.dairiki.org/xface/
$ echo "Hello sci.crypt community. :-)" | d2x
#define image_width 48
#define image_height 48
static unsigned char image_bits[] = {
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x73, 0x63, 0x69, 0x2e, 0x63, 0x72,
0x79, 0x70, 0x74, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74,
0x79, 0x2e, 0x20, 0x3a, 0x2d, 0x29, 0x0a, 0x00, 0xff, 0x00, 0xff, 0x00,
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff
};
Here is the C source code:
// d2x - data to xbm
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define IMAGE_WIDTH 48
#define IMAGE_HEIGHT 48
#define IMAGE_SIZE (IMAGE_WIDTH * IMAGE_HEIGHT / 8) // 288 Bytes
#define INPUT_SIZE IMAGE_SIZE // 288 Bytes
// Function to embed data into an image with checkerboard padding
void encode(uint8_t *image, const uint8_t *data, size_t bytesRead) {
for (size_t i = 0; i < bytesRead; i++) {
image[i] = data[i];
}
// Checkerboard padding
for (size_t i = bytesRead; i < IMAGE_SIZE; i++) {
// Alternate between 0xFF and 0x00 based on row and column
if ((i / IMAGE_WIDTH) % 2 == (i % IMAGE_WIDTH) % 2) {
image[i] = 0xFF; // White
} else {
image[i] = 0x00; // Black
}
}
}
// Function to extract data from an image
void decode(const uint8_t *image, uint8_t *data) {
for (int i = 0; i < INPUT_SIZE; i++) {
data[i] = image[i];
}
}
// Function to write the XBM format
void write_xbm(const uint8_t *image, FILE *out) {
fprintf(out, "#define image_width %d\n", IMAGE_WIDTH);
fprintf(out, "#define image_height %d\n", IMAGE_HEIGHT);
fprintf(out, "static unsigned char image_bits[] = {\n");
for (int i = 0; i < IMAGE_SIZE; i++) {
// Single space before the first hex value on each line
if (i % 12 == 0) {
fprintf(out, " ");
}
// Write the hex value
fprintf(out, "0x%02x", image[i]);
// Add a comma unless it's the last value
if (i < IMAGE_SIZE - 1) {
fprintf(out, ",");
}
// Add a space after each value
fprintf(out, " ");
// Add a newline after every 12 values
if ((i + 1) % 12 == 0 || i == IMAGE_SIZE - 1) {
fprintf(out, "\n");
}
}
fprintf(out, "};\n");
}
// Function to read the XBM format
int read_xbm(FILE *input, uint8_t *image) {
char line[256];
int index = 0;
while (fgets(line, sizeof(line), input)) {
// Skip lines that do not contain hex values
if (!strstr(line, "0x")) {
continue;
}
// Parse hex values
char *token = strtok(line, ",");
while (token != NULL) {
if (sscanf(token, " 0x%02hhx", &image[index]) == 1) {
index++;
}
token = strtok(NULL, ",");
}
}
return index;
}
// Main function
int main(int argc, char *argv[]) {
int mode = 0; // 0 = Encode, 1 = Decode
// Argument check
if (argc > 1) {
if (strcmp(argv[1], "-d") == 0) {
mode = 1; // Decode mode
} else {
fprintf(stderr, "Usage:\n");
fprintf(stderr, " sx Put data (max. 288 bytes) from stdin into XBM format and write to stdout\n");
fprintf(stderr, " sx -d Decode XBM image from stdin and write data to stdout\n");
return 1;
}
}
if (mode == 1) {
// Decode mode
uint8_t image[IMAGE_SIZE] = {0};
int bytesRead = read_xbm(stdin, image);
if (bytesRead != IMAGE_SIZE) {
fprintf(stderr, "Error: Invalid image size (expected %d bytes, got %d)\n", IMAGE_SIZE, bytesRead);
return 1;
}
uint8_t data[INPUT_SIZE] = {0};
decode(image, data);
fwrite(data, 1, INPUT_SIZE, stdout);
} else {
// Encode mode
uint8_t data[INPUT_SIZE] = {0};
size_t bytesRead = fread(data, 1, INPUT_SIZE, stdin);
if (bytesRead > INPUT_SIZE) {
fprintf(stderr, "Error: Input data too large\n");
return 1;
}
uint8_t image[IMAGE_SIZE] = {0};
encode(image, data, bytesRead);
write_xbm(image, stdout);
}
return 0;
}
========== REMAINDER OF ARTICLE TRUNCATED ==========