iOS iP地址在iPs范围内进行比较

时间:2014-02-09 08:44:49

标签: ios iphone objective-c ipad

我正在开发一个显示基于国家/地区内容的应用程序,因此我获得了用户的IP地址,问题是如何检查此IP是否在两个IP之间。例如:

如果我有这个IP:myIP = 127.0.0.1

如何检查是否在此范围之间: IP1 = 2.88.0.0; IP2 = 2.91.255.255;

感谢。

2 个答案:

答案 0 :(得分:2)

127.0.0.1是环回设备的地址。您需要en0或其他任何地址,即连接到wifi /移动网络的设备。 (可以使用getifaddrs()枚举所有设备地址;请参阅此SO question)。

对于IPv4地址,可以使用32位unsigned int表示该值,因此范围更改非常简单:

BOOL inRange = ipAddress >= rangeStart && ipAddress <= endRange;

请参阅此SO question

编辑 OP似乎停留在字符串中使用点符号表示的IP地址转换(即“2.88.0.0”)和我引用的unsigned int至。为此,我将他引用到inet_aton()函数,该函数用于执行该转换。如果您搜索该功能以及如何使用它,您将在互联网上获得许多点击。

编辑2 好的,我会添加一个更完整的答案,因为OP仍有问题:

我认为您使用inet_aton()错过WRT的关键信息是字节顺序。有一个网络字节顺序的概念,这是大端的,因为互联网的创始人使用了Dec PDP 11来开发。现在大多数计算机都是小端。因此,您需要将htonl()添加到混合中,这是从网络转换为主机字节顺序的函数(其中l表示长,实际上是32位)。

所以:

#import <Foundation/Foundation.h>
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>

@interface NetworkStuff : NSObject
- (uint32_t)convertIpAddress:(NSString *)ipAddress;
- (BOOL)ipAddress:(NSString *)ipAddress isBetweenIpAddress:(NSString *)rangeStart
     andIpAddress:(NSString *)rangeEnd;
@end

@implementation NetworkStuff
- (uint32_t)convertIpAddress:(NSString *)ipAddress {
    struct sockaddr_in sin;
    inet_aton([ipAddress UTF8String], &sin.sin_addr);
    return ntohl(sin.sin_addr.s_addr);
}

- (BOOL)ipAddress:(NSString *)ipAddress isBetweenIpAddress:(NSString *)rangeStart
     andIpAddress:(NSString *)rangeEnd {
    uint32_t ip = [self convertIpAddress:ipAddress];
    uint32_t start = [self convertIpAddress:rangeStart];
    uint32_t end = [self convertIpAddress:rangeEnd];
    return ip >= start && ip <= end;
}

@end

#define BOOLSTR(b) (b ? @"YES" : @"NO")

int main()
{  
    @autoreleasepool{
        NetworkStuff *networkStuff = [NetworkStuff new];
        NSLog(@"%@", BOOLSTR([networkStuff ipAddress:@"2.90.1.2" isBetweenIpAddress:@"2.88.0.0" andIpAddress:@"2.91.255.255"]));
        NSLog(@"%@", BOOLSTR([networkStuff ipAddress:@"2.92.1.2" isBetweenIpAddress:@"2.88.0.0" andIpAddress:@"2.91.255.255"]));
    }
    return 0;
}

$ clang -DDEBUG=1 -g -fobjc-arc -o iprange iprange.m -framework Foundation
$ ./iprange
2014-02-10 09:42:29.530 iprange[14693:707] YES
2014-02-10 09:42:29.532 iprange[14693:707] NO

答案 1 :(得分:0)

首先,我使用以下方法将IP地址转换为数字:

-(double)getIpAsNumberr:(NSString *)ip
{
    NSArray *ipParts = [ip componentsSeparatedByString:@"."];
    double result = 0;

    for (int i = 0; i < 4; i++)
    {
        result += [ipParts[i]doubleValue] * (pow(256, (3 - i)));
    }

    return result;
}

转换IP地址后我使用以下方法查找IP地址是否落在某个范围内,如介于2.88.0.0和2.91.255.255之间:

-(BOOL)isBetween:(NSString *)myIPAddress fromRange:(NSString *)from ToRange:(NSString *)to
{
    double myIpAsNumber = [self getIpAsNumberr:myIPAddress];
    double ipFromAsNumber = [self getIpAsNumberr:from];
    double ipToAsNumber = [self getIpAsNumberr:to];

    BOOL inRange = myIpAsNumber >= ipFromAsNumber && myIpAsNumber <= ipToAsNumber;

    return inRange;
}

就是这样。

我用以下的方法将IP地址转换为无符号整数,(对我来说没用,所以我使用了上面的那个):

-(double)getIpAsUnSignedInteger:(NSString *)ip
{
    struct sockaddr_in antelope;
    char *some_addr;
    const char *ipUnsigned = [ip cStringUsingEncoding:NSStringEncodingConversionAllowLossy];

    inet_aton(ipUnsigned, &antelope.sin_addr); // store IP in antelope

    some_addr = inet_ntoa(antelope.sin_addr); // return the IP
    printf("%s\n", some_addr); // prints the IP Address

    // and this call is the same as the inet_aton() call, above:
    antelope.sin_addr.s_addr = inet_addr(ipUnsigned);

    NSString *ipAsNumber = [NSString stringWithFormat:@"%u",antelope.sin_addr.s_addr];
    NSLog(@"ssss == %@",ipAsNumber);

    return [ipAsNumber doubleValue];
}