Вот, собственно, наваял:
#define DIG0(c) (c == '0') // 0
#define DIG1(c) (c == '1') // 1
#define DIG2(c) (c == '2') // 2
#define DIG34(c) (c == '3' || c == '4') // 3
#define DIG5(c) (c == '5') // 4
#define DIG69(c) (c >= '6' && c <= '9') // 5
#define DOT(c) (c == '.') // 6
#define ER 7 // 7
#define SELEVENT(c) (DOT(c) ? 6 : (DIG69(c) ? 5 : (DIG34(c) ? 3 : (DIG0(c) ? 0 : (DIG1(c) ? 1 : (DIG2(c) ? 2 : (DIG5(c) ? 4 : ER)))))))
bool IsIPAddr(const char* str)
{
// x - неизветно, o - известно
enum State {dig0 = 0, digox, digoo, dig1xx, dig2xx, dig25x, dig1ox, dig2ox, dig25o, dig1oo, dig2oo, dot, er};
static const State transfer[][8] = {
{er, er, er, er, er, er, dot, er},
{digoo, digoo, digoo, digoo, digoo, digoo, dot, er},
{er, er, er, er, er, er, dot, er},
{dig1ox, dig1ox, dig1ox, dig1ox, dig1ox, dig1ox, dot, er},
{dig2ox, dig2ox, dig2ox, dig2ox, dig25x, digoo, dot, er},
{dig25o, dig25o, dig25o, dig25o, dig25o, er, dot, er},
{dig1oo, dig1oo, dig1oo, dig1oo, dig1oo, dig1oo, dot, er},
{dig2oo, dig2oo, dig2oo, dig2oo, dig2oo, dig2oo, dot, er},
{er, er, er, er, er, er, dot, er},
{er, er, er, er, er, er, dot, er},
{er, er, er, er, er, er, dot, er},
{dig0, dig1xx, dig2xx, digox, digox, digox, er, er},
{dig0, dig1xx, dig2xx, digox, digox, digox, er, er}
};
State curstate = er;
int dotcount = 0;
while(*str)
{
curstate = transfer[curstate][SELEVENT(*str)];
if(curstate == er) return false;
if(curstate == dot) dotcount++;
if(dotcount > 3) return false;
str++;
}
if(curstate == dot || dotcount < 3) return false;
return true;
}
Интересует правильность работы функции. Ложный негатив я проверил — все правильные (x.x.x.x, где x число от 0 до 255) адреса выдают true. А как обстоит дело с ложным позитивом?
Также интересует возможность оптимизации функции.
Буду благодарен за помощь.
С уважением,
Olegator
... << RSDN@Home 1.1.3 beta 1 >>
20.04.04 07:11: Перенесено модератором из 'C/C++' — OE