isNumeric (Crecreacion de la funcion de VB6).
Publicado: 16 Ago 2011, 22:29
Se estan realizando varios retos en el foro elhacker.net he participado en en el reto de recrear la funcion isnumeric, pero en vb6. la siguiente funcion tiene una alternativa para vb6 mas rapida que la funcion nativa de vb6.
Antes de Le digo que se trabajan las funciones a nivel Bit.
Funcion en VB6
y aqui les dejo la traduccion en C (Esta configurada para trabajar con las Strings de VB6)
Dulces Lunas!¡.
Antes de Le digo que se trabajan las funciones a nivel Bit.
Funcion en VB6
Código: Seleccionar todo
http://foro.elhacker.net/programacion_visual_basic/reto_reemplazo_de_funcion_isnumeric-t336067.0.html;msg1652210#msg1652210
Código: Seleccionar todo
/**
@Autor BlackZeroX
@Web http://infrangelux.sytes.net/blog/
@Reference http://foro.elhacker.net/programacion_visual_basic/reto_reemplazo_de_funcion_isnumeric-t336067.0.html;msg1652210#msg1652210
@Description Libreria para verificar si una Cadena de texto ANSI/UNICODE es numerica con los siguientes formatos:
* ###e[+/-]### {+/-646.45e+546,45}.
* ###d[+/-]### {+/-646.45d+546,45}.
* Base 16 {&H4561abcdef}.
* Base 10 {+/-456,541.456,545}.
@Returns 0 si la cadena no contiene ningun formato.
1 si la cadena pertenece a algun tipo de formato numerico.
**/
#define PUNTO_DECIMAL 0x10000
#define SIGNO_SRC 0x20000
#define NUMBER_HEX 0x40000
#define NUMBER_HEX_ZERO 0x80000
#define NUMBER_HEX_FLAGS (NUMBER_HEX | NUMBER_HEX_ZERO)
#define NUMBER_POW 0x100000
#define NUMBER_POW_FINISH 0x200000
#define NUMBER_POW_FLAGS (NUMBER_POW | NUMBER_POW_FINISH)
#define NUMBER_OF_OK 0x400000
#define NUMBER_OF_FINISH 0x800000
#define NUMBER_OF_FLAGS (NUMBER_OF_OK | NUMBER_OF_FINISH)
DLL_EXPORT int __stdcall IsNumericA (char *pStr) { return IsNumericEx(pStr, 1); }
DLL_EXPORT int __stdcall IsNumericW (char *pStr) { return IsNumericEx(pStr, 2); }
int IsNumericEx (char *pStr, int iStep) {
unsigned int i = 0x0, // For()
iLn = 0x0, // Longitud de pStr.
iData = 0x0; // Xor, Switcher, Contador (QWord).
if (!pStr)
return 0;
iLn = *((int*)(pStr - 0x4));
if (!iLn)
return 0;
for (i = 0; i < iLn; i += iStep) {
if ((iData & NUMBER_HEX) == NUMBER_HEX) {
if (((*pStr >= 0x30) && (*pStr <= 0x39)) ||
((*pStr >= 0x61) && (*pStr <= 0x66)) ||
((*pStr >= 0x41) && (*pStr <= 0x46))) { // Numeros Hexadecimales
if ((iData & NUMBER_OF_FLAGS) == 0x0) // Ceros a la izquierda
iData |= (*pStr == 0x30) ? NUMBER_HEX_ZERO : NUMBER_OF_OK;
switch (iData & NUMBER_OF_FLAGS) {
case NUMBER_OF_OK:
iData++;
if ((iData & 0xFF) == 0x11)
return 0; // QWord (Max Double)
iData |= NUMBER_OF_OK;
if ((iData | NUMBER_HEX_FLAGS) == NUMBER_HEX_FLAGS)
iData ^= NUMBER_HEX_ZERO;
break;
case NUMBER_OF_FINISH:
case NUMBER_OF_FLAGS:
return 0;
break;
}
} else {
switch ((int)(*pStr)) {
case 0x9:
case 0xA:
case 0xB:
case 0xC:
case 0xD:
case 0x24:
case 0x20:
case 0xA0: // Espacios en Blanco
if ((iData | NUMBER_HEX_FLAGS) == NUMBER_HEX_FLAGS)
iData = ((iData ^ NUMBER_HEX_ZERO) | NUMBER_OF_OK);
if ((iData & NUMBER_OF_FLAGS) == NUMBER_OF_OK)
iData |= NUMBER_OF_FINISH;
break;
case 0x0: // NULL Indica que se termina la cadena.
if ((iData & NUMBER_OF_FLAGS) == NUMBER_OF_FINISH)
return 0;
i = iLn; // Exit For.
break;
default:
return 0;
break;
}
}
} else {
if ((*pStr >= 0x30) && (*pStr <= 0x39)) {
iData |= NUMBER_OF_OK;
if ((iData & NUMBER_OF_FINISH) == NUMBER_OF_FINISH)
return 0;
if ((iData & NUMBER_POW_FLAGS) == NUMBER_POW)
iData |= NUMBER_POW_FINISH;
} else {
switch ((int)*pStr) {
case 0x0: // NULL Indica que se termina la cadena.
if ((iData & NUMBER_POW_FLAGS) == NUMBER_POW)
return 0;
i = iLn; // Exit For.
break;
case 0x2E: // "." Solo 1
if (((iData & NUMBER_POW_FLAGS) == NUMBER_POW) ||
((iData & NUMBER_OF_FINISH) == NUMBER_OF_FINISH) ||
((iData & PUNTO_DECIMAL) == PUNTO_DECIMAL))
return 0;
iData |= PUNTO_DECIMAL;
break;
case 0x2B:
case 0x2D: // "+|-" Solo 1
if ((iData & NUMBER_POW_FLAGS) == NUMBER_POW)
iData |= NUMBER_POW_FINISH;
else
if (((iData & NUMBER_OF_OK) == NUMBER_OF_OK) ||
((iData & PUNTO_DECIMAL) == PUNTO_DECIMAL) ||
((iData & SIGNO_SRC) == SIGNO_SRC))
return 0;
if ((iData & NUMBER_OF_FINISH) == NUMBER_OF_FINISH)
return 0;
iData |= SIGNO_SRC;
break;
case 0x2C:
if ( !((iData & NUMBER_OF_OK) == NUMBER_OF_OK) ||
((iData & NUMBER_POW_FLAGS) == NUMBER_POW))
return 0;
break;
case 0x9:
case 0xA:
case 0xB:
case 0xC:
case 0xD:
case 0x24: // Solo se permiten al inicio de un Numero (Espacios en Blanco).
if (((iData & PUNTO_DECIMAL) == PUNTO_DECIMAL) ||
((iData & NUMBER_OF_FINISH) == NUMBER_OF_FINISH) ||
((iData & NUMBER_OF_OK) == NUMBER_OF_OK) ||
((iData & NUMBER_POW_FLAGS) == NUMBER_POW))
return 0;
break;
case 0xA0:
case 0x20: // Se permiten al Inicio/final de un numero.
if ((iData & NUMBER_OF_OK) == NUMBER_OF_OK)
iData |= NUMBER_OF_FINISH;
else
if (((iData & PUNTO_DECIMAL) == PUNTO_DECIMAL) ||
((iData & NUMBER_POW_FLAGS) == NUMBER_POW))
return 0;
break;
case 0x26: // Es un Numero Hexadecimal
if (((iData & NUMBER_OF_FINISH) == NUMBER_OF_FINISH) ||
((iData & NUMBER_OF_OK) == NUMBER_OF_OK) ||
((iData & SIGNO_SRC) == SIGNO_SRC) ||
((iData & PUNTO_DECIMAL) == PUNTO_DECIMAL) ||
((iData & NUMBER_POW_FLAGS) == NUMBER_POW))
return 0;
i++;
pStr += iStep;
if ((*pStr == 0x48) || (*pStr == 0x68)) {
iData |= NUMBER_HEX;
iData ^= 0xFF000000;
} else {
--i;
pStr -= iStep;
}
break;
case 0x44:
case 0x45:
case 0x64:
case 0x65: // Numeros en Formato ###e-###, ###e+###
if (((iData & NUMBER_OF_FINISH) == NUMBER_OF_FINISH) ||
((iData & NUMBER_POW) == NUMBER_POW))
return 0;
if ((iData & NUMBER_OF_OK) == NUMBER_OF_OK) {
iData |= NUMBER_POW;
if ((iData & SIGNO_SRC) == SIGNO_SRC)
iData ^= SIGNO_SRC; // Permitimos nuevamente los signos "+" y "-".
} else {
return 0;
}
break;
default:
return 0;
break;
} // switch()
} // if()
} // if()
pStr += iStep;
} // For()
switch (iData & NUMBER_OF_FLAGS) {
case NUMBER_OF_OK:
case NUMBER_OF_FLAGS:
return 1;
break;
default:
switch (iData & NUMBER_HEX_FLAGS) {
case NUMBER_HEX_FLAGS:
return 1;
}
}
return 0;
}