/***************
*
* g:\exe\txl\src\txlpswd.c
*/
#include "txl.h"

unsigned char *get_use_string()
{
	int i, dst;
	static unsigned char str[132];
	srand(0);
	strcpy(str, "!#%&@$~(^_-)/ｦ={}?,.*");
	for (i = 'A'; i <= 'Z'; i++) {
		str[21 + i - 'A'] = (char)(i);
	}
	for (i = '0'; i <= '9'; i++) {
		str[47 + i - '0'] = (char)(i);
	}
	for (i = 'a'; i <= 'z'; i++) {
		str[57 + i - 'a'] = (char)(i);
	}
	for (i = 'ｱ'; i <= 'ﾝ'; i++) {
		str[83 + i - 'ｱ'] = (char)(i);
	}

	str[128] = NUL;
	for (i = 0; i < 128; i++) {
		dst = rand() % 128;
		str[131] = str[i];
		str[i] = str[dst];
		str[dst] = str[131];
	}

	return (str);
}

int getposnum(int c)
{
	static unsigned char *str = NULL;
	unsigned char *tmp;
	if (str == NULL) {
		str = get_use_string();
	}
	if ((tmp = strchr(str, c)) == NULL) {
		return (-1);
	}
	return ((int)(tmp - str));

}

int getposchr(int c)
{
	static unsigned char *str = NULL;

	if (str == NULL) {
		str = get_use_string();
	}
	if (c > 127) {
		return (-1);
	}
	return (str[c]);
}

void expand_passwd(char *val[])
{
	int pos, c, i, sum, len, c1, c2, c3, plen;
	FILE *fw;
	unsigned char passwd[16];
	unsigned char code[32];

	for (i = 0; i < 16; i++) {
		passwd[i] = 0;
	}

	if ((fw = fopen(val[1], "wb")) == NULL) {
		Exit(1);
	}

	if (strlen(val[0]) > 31) {
		fputs("Error", fw);
		fclose(fw);
		Exit(1);	/* コードデータが長過ぎ */
	}
	strcpy(code, val[0]);
	len = strlen(code);

	sum = 0;
	for (i = 0; i < len - 2; i++) {
		sum += code[i];
	}
	if (code[len - 2] != getposchr(sum / 128) ||
			code[len - 1] != getposchr(sum % 128)) {
		fputs("Error(SUM)", fw);
		fclose(fw);
		Exit(1);
	}
	if (code[0] != '0') {
		fputs("Error(TAG)", fw);
		fclose(fw);
		Exit(1);
	}
	c1 = getposnum(code[1]);
	c2 = getposnum(code[2]);
	c3 = getposnum(code[3]);
	plen = (128 + c3 - abs(c1 - c2)) % 128;
	if (plen > 9) {
		fputs("Error(LENGTH)", fw);
		fclose(fw);
		Exit(1);
	}

	c = (abs(c3 - c1) + plen) % 128;
	pos = 0;
	for (i = 4; i < 4 + plen; i++) {
		c1 = getposnum(code[i]);
		passwd[pos++] = (c1 + c + i - 4) + 1;
	}									/* ↑ １スライド */

	fputs(passwd, fw);
	fclose(fw);
	Exit(0);
}

void compress_passwd(char *val[])
{
	int pos, c, i, sum, c1, c2, c3;
	FILE *fw;
	unsigned char passwd[16];
	unsigned char code[32];

	getposchr(0);		/* 初回はrandを初期化するのでダミー呼び出し */
	getposnum('0');		/* 上に同じ */
	srand((unsigned int)(clock() & 0x0ffff));
	for (i = 1; i < 32; i++) {
		code[i] = 0;
	}
	pos = 0;
	code[pos++] = '0';

	if ((fw = fopen(val[1], "wb")) == NULL) {
		Exit(1);
	}

	if (strlen(val[0]) > 9) {
		fputs("Error(LENGTH)", fw);
		fclose(fw);
		Exit(1);	/* パスワードが長過ぎ */
	}
	strcpy(passwd, val[0]);
	while (strlen(passwd) < 10) {
		strncat(passwd, val[0], 10 - strlen(passwd));
	}
	c1 = rand() % 128;
	c2 = rand() % 128;
	c3 = (abs(c1 - c2) + strlen(val[0])) % 128;
	code[pos++] = getposchr(c1);
	code[pos++] = getposchr(c2);
	code[pos++] = getposchr(c3);

	c = (abs(c3 - c1) + strlen(val[0])) % 128;
	for (i = 0; i < 10; i++) {
		code[pos++] = getposchr((256 + passwd[i] - c - i) % 128);
	}
	sum = 0;
	for (i = 0; code[i] != NUL; i++) {
		sum += code[i];
	}
	code[pos++] = getposchr(sum / 128);
	code[pos++] = getposchr(sum % 128);
	fputs(code, fw);
	fclose(fw);
	Exit(0);
}

