Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
vochant committed Nov 22, 2023
1 parent dbfb5d8 commit 10415b2
Show file tree
Hide file tree
Showing 5 changed files with 489 additions and 0 deletions.
221 changes: 221 additions & 0 deletions codec.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
#ifndef __LIB_CRYPTXX
#define __LIB_CRYPTXX

#include "lib.hpp"

void BinaryOutput(FILE* fp, const char* str, long long len) {
for (long long i = 0; i < len; i++) {
putc(str[i], fp);
}
}

void ReadBytes(FILE* fp, char* str, long long len) {
for (long long i = 0; i < len; i++) {
str[i] = getc(fp);
// printf("NSG %d\n", ((unsigned char*)str)[i]);
}
}

#define charCodeAt(__ch, __pos) (unsigned char)((__ch >> (__pos << 3)) & 0xff)

class EncodeArchive {
private:
string f;
long long arcVersion;
string sourceFiles[65536];
long long ptrAt;
long long fileCount;
long long contentLengths[65536];
FILE *fp;
bool e;
public:
EncodeArchive(string of) {
e = false;
f = of;
errno_t err = fopen_s(&fp, f.c_str(), "wb");
if (err) {
printf("Failed when opening the output file \"%s\", code %d.\n", f.c_str(), err);
e = true;
} else {
ptrAt = 0;
fileCount = 0;
arcVersion = CURRENT_VERSION;
}
}
void CreateHeader() {
BinaryOutput(fp, "LLAR\x00\x00\x00\x00\x0AMirekintoc", 19);
ptrAt += 19;
}
bool Error() {
return e;
}
void MakeTable() {
unsigned char ver[8];
for (int i = 0; i < fileCount; i++) {
for (int j = 7; j >= 0; j--) {
ver[7 - j] = charCodeAt(sourceFiles[i].length(), j);
}
BinaryOutput(fp, (char*)ver, 8);
BinaryOutput(fp, sourceFiles[i].c_str(), sourceFiles[i].length());
for (int j = 7; j >= 0; j--) {
ver[7 - j] = charCodeAt(contentLengths[i], j);
}
BinaryOutput(fp, (char*)ver, 8);
ptrAt += 16 + sourceFiles[i].length();
}
putc(0x7F, fp);
ptrAt++;
}
void AddFile(string f) {
printf("Adding file \"%s\"...\n", f.c_str());
sourceFiles[fileCount] = f;
contentLengths[fileCount] = gfsize(f.c_str());
if(contentLengths[fileCount] == -1) {
e = true;
}
fileCount++;
}
void ConstructFile() {
printf("Creating header...\n");
CreateHeader();
printf("Making table...\n");
MakeTable();
for (int i = 0; i < fileCount; i++) {
printf("Processing file \"%s\"...\n", sourceFiles[i].c_str());
FILE* f = fopen(sourceFiles[i].c_str(), "rb");
Mask0 msk;
msk.output_mask(fp);
msk.stream_encode(contentLengths[i], f, fp);
fclose(f);
}
printf("Done!\n");
}
};

class DecodeArchive {
private:
string f;
long long contentLengths[65536];
long long beginAddr[65536];
string fileNames[65536];
long long headerLength, fileCount;
FILE *fp;
bool e;
public:
DecodeArchive(string str) {
f = str;
char hdr[256];
e = false;
unsigned char* ref = (unsigned char*)hdr;
errno_t err = fopen_s(&fp, str.c_str(), "rb");
if (err) {
e = true;
printf("Failed when opening file \"%s\", code %d.\n", str.c_str(), err);
} else {
ReadBytes(fp, hdr, 4);
hdr[4] = 0;
string s = hdr;
if (s != "LLAR") {
e = true;
printf("File \"%s\" is not a valid LLAR file.\n", str.c_str());
} else {
int ver;
ReadBytes(fp, hdr, 4);
ver = (ref[0] << 24) + (ref[1] << 16) + (ref[2] << 8) + ref[3];
if (ver > 0) {
e = true;
printf("Unsupported file version %d\n", ver);
}
}
}
}
void GetInformations() {
char hdr[256];
unsigned char* ref = (unsigned char*)hdr;
ReadBytes(fp, hdr, 1);
int cop = hdr[0];
ReadBytes(fp, hdr, cop);
hdr[cop] = 0;
printf("Notice: This file is generated by %s\n", hdr);
headerLength = 9 + cop;
fileCount = 0;
while (true) {
ReadBytes(fp, hdr, 1);
if (hdr[0] == 0x7F) {
break;
}
ReadBytes(fp, hdr + 1, 7);
long long nl = 0;
for (int i = 0; i < 8; i++) {
nl |= ref[i] << ((7 - i) << 3);
// printf("ADD %lld %d %d\n", ref[i] << ((7 - i) << 3), hdr[i], ref[i]);
}
ReadBytes(fp, hdr, nl);
hdr[nl] = 0;
printf("New file got: \"%s\"\n", hdr);
fileNames[fileCount] = hdr;
ReadBytes(fp, hdr, 8);
contentLengths[fileCount] = 0;
for (int i = 0; i < 8; i++) {
contentLengths[fileCount] |= ref[i] << ((7 - i) << 3);
}
headerLength += 16 + nl;
fileCount++;
}
headerLength++;
long long ptrAt = headerLength;
for (int i = 0; i < fileCount; i++) {
beginAddr[i] = ptrAt;
ptrAt += contentLengths[i] + 256;
}
}
bool Error() {
return e;
}
void ExtractEach(string str) {
printf("Extracting \"%s\"...\n", str.c_str());
int id = -1;
for (int i = 0; i < fileCount; i++) {
if (fileNames[i] == str) {
id = i;
break;
}
}
if (!~id) {
printf("Cannot find file \"%s\" in archive \"%s\".\n", str, f);
e = true;
return;
}
FILE *f1;
errno_t err = fopen_s(&f1, str.c_str(), "wb");
if (err) {
printf("Failed when opening file \"%s\", code %d.\n", str, err);
e = true;
return;
}
int err1 = _fseeki64(fp, beginAddr[id], SEEK_SET);
if (err1) {
printf("Failed when moving cursor in \"%s\", code %d.\n", str, err1);
}
Mask0 msk(fp);
msk.stream_decode(contentLengths[id], fp, f1);
fclose(f1);
}
void ExtractAll() {
FILE* f1;
for (int i = 0; i < fileCount; i++) {
printf("Extracting \"%s\"...\n", fileNames[i].c_str());
errno_t err = fopen_s(&f1, fileNames[i].c_str(), "wb");
if (err) {
printf("Failed when opening file \"%s\", code %d.\n", fileNames[i], err);
e = true;
return;
}
Mask0 msk(fp);
msk.stream_decode(contentLengths[i], fp, f1);
fclose(f1);
}
}
};

#endif
12 changes: 12 additions & 0 deletions compile.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@echo off

setlocal

cd /d %~dp0
echo Compiling 'llarm.cpp' into 'llarm.exe'...
g++ llarm.cpp -O2 -static -Wl,--stack=256000000 -o llarm.exe
echo Compiling 'simpllar.cpp' into 'simpllar.exe'...
g++ simpllar.cpp -O2 -static -Wl,--stack=256000000 -o simpllar.exe
echo Done!

endlocal
97 changes: 97 additions & 0 deletions lib.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#ifndef __LIB_CRYPT
#define __LIB_CRYPT

#define CURRENT_VERSION 0

#include <bits/stdc++.h>
using namespace std;

mt19937 rnd;

void Init() {
rnd.seed(random_device{}());
}

class Mask0 {
private:
unsigned char conv[256], dconv[256];
public:
Mask0() {
bool vis[258];
memset(vis, 0, sizeof(vis));
int nex, cnt, cur;
for (int i = 0; i < 256; i++) {
nex = rnd() % (256 - i);
cnt = 0;
cur = 0;
while (cnt <= nex) {
if (!vis[cur]) {
cnt++;
}
cur++;
}
conv[i] = cur - 1;
vis[cur - 1] = true;
}
for (int i = 0; i < 256; i++) {
dconv[conv[i]] = i;
}
}
Mask0(FILE *s) {
for (int i = 0; i < 256; i++) {
conv[i] = getc(s);
}
for (int i = 0; i < 256; i++) {
dconv[conv[i]] = i;
}
}
void output_mask(FILE* out) {
for (int i = 0; i < 256; i++) {
putc(conv[i], out);
}
}
void stream_encode(long long content_length, FILE* in, FILE* out) {
unsigned char ch, xorbase = 0;
for (long long i = 0; i < content_length; i++) {
ch = getc(in);
xorbase ^= ch;
putc(conv[xorbase], out);
}
}
void stream_decode(long long content_length, FILE* in, FILE* out) {
unsigned char ch, prev = conv[0];
for (long long i = 0; i < content_length; i++) {
ch = getc(in);
putc(dconv[prev] ^ dconv[ch], out);
prev = ch;
}
}
};

long long gfsize(const char *fn) {
if (!fn) {
return -1;
}
FILE *fp = NULL;
long long res;
errno_t err0 = fopen_s(&fp, fn, "rb");
if (err0 != 0) {
printf("Failed when opening file \"%s\", code %d.\n", fn, err0);
return -1;
}
int err1 = _fseeki64(fp, 0, SEEK_END);
if (err1 != 0) {
printf("Failed when moving cursor in file \"%s\" (SEEK_END), code %d.\n", fn, err1);
return -1;
}
res = _ftelli64(fp);
int err2 = _fseeki64(fp, 0, SEEK_SET);
if (err2 != 0) {
printf("Failed when moving cursor in file \"%s\" (SEEK_SET), code %d.\n", fn, err1);
return -1;
}
fclose(fp);
return res;
}

#endif
Loading

0 comments on commit 10415b2

Please sign in to comment.