Hex/Non-decimal base support
Displaying 1-2 of 2 total.
1
Please enter a numerical value for the importance of this sticky.
Enter 0 to unsticky.
Goldenrod111

I've been working on a base conversion and hex tool file. I think that it's working now, but I'd like someone to proofread it, to make sure before I post it. The full text is below. Tell me if I made any mistakes, or wrote anything redundant. The site was down as I was writing this, so I wasn't able to check the built-in functions. I do apologize for the size of this thing, but I couldn't figure out any way to make it smaller--the "height", "width", and "overflow" properties weren't working.

//----------------------------------------------------------------------------------------------------------------------------------------------
// Change-of-Base Formulae
//----------------------------------------------------------------------------------------------------------------------------------------------
//
// This code was written to allow VERGE to understand, to some extent, different bases, mainly hexadecimal and binary. It is still rather
// cumbersome to use, but it will likely be that way until this function is built directly into the engine itself. As it is, anything that is
// not base ten (decimal) is stored as a string, to avoid accidentally mixing bases.
//
// Feel free to learn from and edit this code. I, and likely some other users, would be interested in any streamlining or extending that you do
// to this, so you are encouraged to share any edits you create. Beyond that, though, you are only required to not claim that you wrote it all
// yourself--give credit to the designers. You may use this royalty-free, and for any games, personal, freeware, or commercial, that you create.
// If you want, tell us that you are using it. It's always nice to know when people like something you've created. However, you may not make a
// profit off of this file directly--you may repackage and redistribute it, but you can only sell this as a component of a finished product.
//
//----------------------------------------------------------------------------------------------------------------------------------------------
// Included functions
//----------------------------------------------------------------------------------------------------------------------------------------------
//
// ConvertNum( string, int, int, optional int );
// Number to convert (as a string), original base, target base, left-padding of result
// Will convert a number from one numeral base to another (e.g. binary to hexadecimal).
// Returns converted number as string
//
// AddBase( string, int, string, int, int );
// First number in operation (as a string), base of first number, second number (as a string), base of second number, base of answer
// Will add two numbers of any numeral base, and can give the answer in a related or unrelated base.
// Returns answer as string
//
// SubtractBase( string, int, string, int, int );
// First number in operation (as a string), base of first number, second number (as a string), base of second number, base of answer
// Will subtract two numbers of any numeral base, and can give the answer in a related or unrelated base.
// Returns answer as string
//
// MultiplyBase( string, int, string, int, int );
// First number in operation (as a string), base of first number, second number (as a string), base of second number, base of answer
// Will multiply two numbers of any numeral base, and can give the answer in a related or unrelated base.
// Returns answer as string
//
// DivideBase( string, int, string, int, int );
// First number in operation (as a string), base of first number, second number (as a string), base of second number, base of answer
// Will divide two numbers of any numeral base, and can give the answer in a related or unrelated base.
// Returns answer as string
//
// ModuloBase( string, int, string, int, int );
// First number in operation (as a string), base of first number, second number (as a string), base of second number, base of answer
// Will preform a modulo operation on two numbers of any numeral base, and can give the answer in a related or unrelated base.
// Returns answer as string
//
// ConvertString( string, int, int, int, bool );
// String to convert, original base, target base, number of digits (see below), include null characters in conversion
// Will encode/decode an ASCII string using chosen numeral base, with the non-decimal digits padded to the specified number of digits
// (e.g. a padding of two would produce "00", and split "000000" into "00 00 00").
// Either the original or the target base must be 10 (decimal).
// Returns converted string
//
// ConvertToHex( string, [BIG_ENDIAN | LITTLE_ENDIAN], int );
// String to convert, record in big or little endian format, number of bytes to pad answer
// Will convert a decimal string into hex values, using either big or little endian encoding.
// Returns converted number as string
//
// ConvertToBinary( string, [BIG_ENDIAN | LITTLE_ENDIAN], int );
// String to convert, record in big or little endian format, number of bytes to pad answer
// Will convert a decimal string into binary, using either big or little endian encoding.
// Returns converted number as string
//
// ConvertFromHex( string, [BIG_ENDIAN | LITTLE_ENDIAN], );
// String to convert, read in big or little endian format
// Will convert a string of hex values into decimal characters, using either big or little endian encoding.
// Returns converted number as string
//
// ConvertFromBinary( string, [BIG_ENDIAN | LITTLE_ENDIAN], );
// String to convert, read in big or little endian format
// Will convert a string of binary values into decimal characters, using either big or little endian encoding.
// Returns converted number as string
//
// ReadHexAddress( string, string, string, [BIG_ENDIAN | LITTLE_ENDIAN] );
// String to read from, hex address of starting byte, hex address of ending byte, read in big or little endian format
// Will read a sequence of bytes in hex from address one to address two, inclusive, using either big or little endian encoding.
// Returns hex values as string
//
// WriteHexAddress( string, string, string, [BIG_ENDIAN | LITTLE_ENDIAN] );
// String to overwrite/add to, hex values to add, hex address of starting byte, record in big or little endian format
// Will write provided hex values over current at the specified location, using either big of little endian encoding.
// Returns updated string
//
// WriteHexFile( string, string, string, [BIG_ENDIAN | LITTLE_ENDIAN] );
// File to overwrite/add to, hex values to add, hex address of starting byte, record in big or little endian format
// Will write provided hex values over current at the specified location in the file, using either big of little endian encoding.
// Returns nothing (file saved and closed)
//
//----------------------------------------------------------------------------------------------------------------------------------------------
// End documentation
//----------------------------------------------------------------------------------------------------------------------------------------------


string ConvertNum(string num, int from, int to, ... dig) {
int i, test, fin;
string final;
if (from == to) return num;
else if (from == 10) {
test = val(num);
while ((to ^ i) <= val(num)) i ++;
while (i >= 0) {
if ((test / (to ^ i)) < 10) final = final + str(test / (to ^ i));
else if ((test / (to ^ i)) < 36) final = final + chr(65 + ((test / (to ^ i)) - 10));
else if ((test / (to ^ i)) < 62) final = final + chr(97 + ((test / (to ^ i)) - 36));
else final = final + chr(128 + ((test / (to ^ i)) - 62));
i --;
}
}
else if (to == 10) {
if (from < 32) num = ToUpper(num);
for (i = 0; len(num); i ++) {
if (asc(mid(num, len(num) - (i + 1), 1)) <= 57) test = (asc(mid(num, len(num) - (i + 1), 1)) - 48) * (from ^ i);
else if (asc(mid(num, len(num) - (i + 1), 1)) <= 90) test = (asc(mid(num, len(num) - (i + 1), 1)) - 55) * (from ^ i);
else if (asc(mid(num, len(num) - (i + 1), 1)) <= 122) test = (asc(mid(num, len(num) - (i + 1), 1)) - 61) * (from ^ i);
else test = (asc(mid(num, len(num) - (i + 1), 1)) - 66) * (from ^ i);
fin += test;
}
final = str(fin);
}
else final = ConvertNum(ConvertNum(num, from, 10), 10, to);
if ((dig.length != 0) && (len(final) < dig.int[0])) while (len(final) < dig.int[0]) final = "0" + final;
return final;
}

string ConvertString(string conv, int from, int to, int dig, int null) {
int i;
string final;
if ((from != 10) && (to != 10)) { MessageBox("ConvertString() requires that either the 'from' or the 'to' value (2nd and 3rd) be 10."); return ""; }
else if ((from == 10) && (to == 10)) final = conv;
else if (from == 10) for (i = 0; len(conv); i ++) if ((asc(mid(conv, i, 1)) != 0) || (null == TRUE)) final += ConvertNum(str(asc(mid(conv, i, 1))), 10, to, dig);
else {
while (len(conv) % dig > 0) conv = chr(0) + conv;
for (i = 0; len(conv) / dig; i += dig) if ((asc(mid(conv, i, dig)) != 0) || (null == TRUE)) final += str(asc(ConvertNum(mid(conv, i, dig), from, 10)));
}
return final;
}

string AddBase(string num1, int base1, string num2, int base2, int basef) {
int num101 = val(ConvertNum(num1, base1, 10));
int num102 = val(ConvertNum(num2, base2, 10));
return ConvertNum(str(num101 + num102), 10, basef);
}
string SubtractBase(string num1, int base1, string num2, int base2, int basef) {
int num101 = val(ConvertNum(num1, base1, 10));
int num102 = val(ConvertNum(num2, base2, 10));
return ConvertNum(str(num101 - num102), 10, basef);
}
string MultiplyBase(string num1, int base1, string num2, int base2, int basef) {
int num101 = val(ConvertNum(num1, base1, 10));
int num102 = val(ConvertNum(num2, base2, 10));
return ConvertNum(str(num101 * num102), 10, basef);
}
string DivideBase(string num1, int base1, string num2, int base2, int basef) {
int num101 = val(ConvertNum(num1, base1, 10));
int num102 = val(ConvertNum(num2, base2, 10));
return ConvertNum(str(num101 / num102), 10, basef);
}
string ModuloBase(string num1, int base1, string num2, int base2, int basef) {
int num101 = val(ConvertNum(num1, base1, 10));
int num102 = val(ConvertNum(num2, base2, 10));
return ConvertNum(str(num101 % num102), 10, basef);
}

#define BIG_ENDIAN 0
#define LITTLE_ENDIAN 1
string ConvertToHex(string conv, int endian, int byte) {
byte = max(byte, 1);
string final;
if (endian == BIG_ENDIAN) final = ConvertString(conv, 10, 16, 2, TRUE);
else {
while (val(conv) % 2 != 0) conv = "0" + conv;
while (len(conv) > 0) { final += right(conv, 2); conv = left(conv, len(conv) - 2); }
final = ConvertString(final, 10, 16, 2, TRUE);
}
if (len(final) > (byte * 2)) MessageBox("'0x" + final + "' is greater than the number of requested bytes (" + str(byte) + ").");
while (len(final) < (byte * 2)) final = "0" + final;
return final;
}
string ConvertFromHex(string conv, int endian) {
string final;
if (endian == BIG_ENDIAN) return ConvertString(conv, 16, 10, 2, FALSE);
else {
while (val(conv) % 2 != 0) conv = "0" + conv;
while (len(conv) > 0) { final += right(conv, 2); conv = left(conv, len(conv) - 2); }
final = ConvertString(final, 16, 10, 2, FALSE);
}
}

string ConvertToBinary(string conv, int endian, int byte) {
byte = max(byte, 1);
string final;
if (endian == BIG_ENDIAN) final = ConvertString(conv, 10, 2, 4, TRUE);
else {
while (val(conv) % 4 != 0) conv = "0" + conv;
while (len(conv) > 0) { final += right(conv, 4); conv = left(conv, len(conv) - 4); }
final = ConvertString(final, 10, 2, 4, TRUE);
}
if (len(final) > (byte * 4)) MessageBox("'" + final + "' is greater than the number of requested bytes (" + str(byte) + ").");
while (len(final) < (byte * 4)) final = "0" + final;
return final;
}
string ConvertFromBinary(string conv, int endian) {
string final;
if (endian == BIG_ENDIAN) return ConvertString(conv, 2, 10, 4, FALSE);
else {
while (val(conv) % 4 != 0) conv = "0" + conv;
while (len(conv) > 0) { final += right(conv, 4); conv = left(conv, len(conv) - 4); }
final = ConvertString(final, 2, 10, 4, FALSE);
}
}

string ReadHexAddress(string hex, string hstart, string hend, int endian) {
int start = val(ConvertNum(hstart, 16, 10));
int end = val(ConvertNum(hend, 16, 10));
string conv = mid(hex, start * 2, (start - end) * 2);
return ConvertFromHex(conv, endian);
}

string WriteHexAddress(string hex, string add, string address, int endian) {
string final;
int start = val(ConvertNum(address, 16, 10)), i;
while (len(add) % 2 != 0) add = "0" + add;
if (endian == LITTLE_ENDIAN) {
for (i = 0; len(add) / 2; i += 2) {
final = mid(add, i * 2, 2 ) + final;
}
}
else final = add;
for (i = start; len(add); i += 2) {
hex = left(hex, i) + mid(final, i, 2) + right(hex, max(len(hex) - (i + 1), 0));
}
return hex;
}

void WriteHexFile(string file, string add, string address, int endian) {
string final;
int hex = FileOpen(file, FILE_WRITE), i;
while (len(add) % 2 != 0) add = "0" + add;
if (endian == LITTLE_ENDIAN) {
for (i = 0; len(add) / 2; i += 2) {
final = mid(add, i * 2, 2 ) + final;
}
}
else final = add;
FileSeekPos(hex, val(ConvertNum(address, 16, 10)), SEEK_SET);
for (i = 0; len(add) / 2; i += 2) {
FileWriteByte(hex, val(ConvertNum(mid(final, i, 2), 16, 10)));
}
FileClose(hex);
}

Posted on 2010-08-31 23:31:15

Goldenrod111

I have realized that most of the few functions that do work would need almost a complete rewrite to be optimized, and many can be done much more easily with built-in functions, so I will not be updating this. If anyone wants to take it on, though, feel free!

Posted on 2010-09-06 18:00:18


Displaying 1-2 of 2 total.
1
 
Newest messages

Ben McGraw's lovingly crafted this website from scratch for years.
It's a lot prettier this go around because of Jon Wofford.
Verge-rpg.com is a member of the lunarnet irc network, and would like to take this opportunity to remind you that regardless how babies taste, it is wrong to eat them.