Ir para conteúdo
  • Cadastre-se
Fernando Mercês

Converter IPv4 inteiro em xxx.xxx.xxx.xxx

Posts Recomendados

// Código em C

int i = 3232235521;
 
printf("%d.%d.%d.%d\n",
(>>24) & 0xff,
(i>>16) & 0xff,
(i>>8) & 0xff,
i > 0xff);
 
/* Saída: 192.168.0.1 */

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Fala Brother,

Eu vi teu código em C aqui em cima, e comecei a pensar em fazer a operação reversa (ip => int). Uma coisa foi levando a outra, e no fim eu fiz isso. =D

Pra o código funcionar:

  1. Cola esse código em um arquivo de nome ip2int.c
  2. Compila com - gcc -o ip2int ip2int.c
  3. Cria um link simbólico - ln -s ip2int int2ip
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* 
 *
 * Se precisar testar o programa
 * O inteiro 3232235521 gera o IP 192.168.0.1
 *
 */

int main(int argc, unsigned char **argv){

  // Como usar o programa
  if(argc != 2){
    printf("Uso:\n\nip2int: <ip address>\nint2ip: <inteiro>\n");
    return 1;
  }

  // Basename
  const char *exename = strrchr(argv[0], '/');
  if (exename)
    // skip past the last /
    ++exename;   
  else
    exename = argv[0];

  if(strcmp(exename,"int2ip")==0){  // Se o nome do binario for int2ip
    int i = atoi(argv[1]);
  
    printf("%d.%d.%d.%d\n",
    (i>>24) & 0xff,
    (i>>16) & 0xff,
    (i>>8) & 0xff,
    i & 0xff);
  }
  else if (strcmp(exename,"ip2int")==0){  // Se o nome do binario for ip2int
    const char *sourceString = argv[1];
    unsigned short len=0;
    unsigned char  cnt=0,cnt1=0,i,buf[5];
    unsigned int output = 0, oct = 0;
             
    len=strlen(sourceString);
    for(i=0;i<len;i++) {
      if(sourceString[i]!='.'){
        buf[cnt++] =sourceString[i];
      }
      if(sourceString[i]=='.' || i==len-1){
        buf[cnt]='\0';
        cnt=0;
        oct=atoi(buf);
        output = output<<8;
        output |= oct;
        if(oct>255){
          printf("IP address invalido - %u\n",oct);
          return 1;
        }
      }
    }
    printf("%u\n",output);
  } else {
    printf("Tenha certeza que o binario tenha o nome ip2int\ne crie um link simbolico para ele chamado int2ip."); // Se o nome do binario for qualquer outra coisa diferente
  }
  return 0;
}

Se vc chamar ./ip2int 192.168.0.1   , ele cospe 3232235521.

Se vc chamar ./int2ip 3232235521  , ele cospe 192.168.0.1

Compartilhando...  =D

Abs!

  • Agradecer 1
  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá @Baracat,

Um dica para simplificar o parsing do IP é utilizand o sscanf():

$ ./ip2int 192.168.0.1
192.168.0.1 -> 3232235521

Segue o código:

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
	if (argc != 2) {
		printf ("Use: %s <IP>", argv[0]);
		return 0;
	}

	unsigned int ip[4];

	if (sscanf(argv[1], "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) != 4) {
		puts ("Invalid IP format (xxx.xxx.xxx.xxx).");
		return -1;
	}

	printf ("%s -> %u", argv[1],
			(ip[0] << 24) +
			(ip[1] << 16) +
			(ip[2] << 8) +
			(ip[3])
		);

	return 0;
}

 

Porém já existem funções espeçificas para fazer o que estamos tentando fazer:

https://www.tutorialspoint.com/unix_sockets/ip_address_functions.htm

Abraços

  • l33t 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ao usar conversores "%d" não estão verificando se o valor é negativo ou superior a 255... Que tal:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>

static int str2ip4 ( char *, uint32_t * );

int main ( int argc, char *argv[] )
{
  uint32_t ip;

  if ( ! *++argv )
  {
    fprintf ( stderr, "Usage: %s ipv4string\n", * ( argv - 1 ) );
    return EXIT_FAILURE;
  }

  if ( ! str2ip4 ( *argv, &ip ) )
  {
    fputs ( "ERROR: Invalid IPv4 string.\n", stderr );
    return EXIT_FAILURE;
  }

  // ESSA extensão (o 1$ e o 2$ nos conversores) é do GCC!!!
  printf ( "%1$s -> %2$" PRIu32 " (%2$#" PRIx32 ")\n", *argv, ip );

  return EXIT_SUCCESS;
}

int str2ip4 ( char *s, uint32_t *ip )
{
  char *p, *q, *r, *t;
  int count;
  unsigned long n;

  p = strdup ( s ); // para garantir que estamos trabalhando com uma cópia
  // que possa ser escrita.

  *ip = 0;
  q = p;
  t = strchr ( q, '.' );

  if ( t )
    *t++ = '\0';

  count = 1;

  while ( q )
  {
    if ( ! isdigit ( *q ) )
    {
      free ( p );
      return 0;
    }

    r = NULL;
    n = strtoul ( q, &r, 10 );

    if ( errno == ERANGE || n > 255 || *r )
    {
      free ( p );
      return 0; // falha!
    }

    *ip <<= 8;
    *ip |= ( uint8_t ) n;

    q = t;

    if ( t )
    {
      count++;
      t = strchr ( q, '.' );

      if ( t )
        *t++ = '\0';
    }
  }

  free ( p );

  return count == 4;
}

 

Editado por fredericopissarra

Compartilhar este post


Link para o post
Compartilhar em outros sites

Claro, outra maneira de fazer é usando getaddrinfo(). Vantagem: suporta IPv6 tb. Desvantagens: Há tentariva de resolver nome; vários registros podem ser retornados (inclusive IPv4 mapeado em IPv6)....

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

×