Re: Comparing first 3 numbers of a IPv4 address?

Lists: pgsql-general
From: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Comparing first 3 numbers of a IPv4 address?
Date: 2010-11-20 13:31:09
Message-ID: AANLkTik-w5syJoXZRd6Y7LyJvpQAvHKBQ6iOBqTVzbhy@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Hello,

I'm trying to program a PHP-script, where users
can rate the "goodness" of the other players:

create table pref_rep (
id varchar(32) references pref_users(id) check (id <> author),
author varchar(32) references pref_users(id),
author_ip inet,
good boolean,
last_rated timestamp default current_timestamp
);

To (try to) prevent tampering I'd like to delete
entries for the same id coming
from the same IP in the course of last hour:

create or replace function pref_update_rep(_id varchar,
_author varchar, _author_ip inet,
_good boolean) returns void as $BODY$
begin

delete from pref_rep
where id = _id and
author_ip = _author_ip and
age(to_timestamp(last_rated)) < interval '1 hour';

update pref_rep set
author = _author,
author_ip = _author_ip,
good = _good,
last_rated = current_timestamp
where id = _id and author = _author;

if not found then
insert into pref_rep(id, author, author_ip, good)
values (_id, _author, _author_ip, _good);
end if;
end;
$BODY$ language plpgsql;

I have 2 questions please:

1) if I'd like to compare just the first 3 numbers of
the IP address instead of the 4, how can I do it?
(yes, I know about the A,B,C type of IPv4 networks...)

2) Do I need to add an index to my table
or are id and author indexed already?

Thank you!
Alex


From: Dmitriy Igrishin <dmitigr(at)gmail(dot)com>
To: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Comparing first 3 numbers of a IPv4 address?
Date: 2010-11-20 14:16:47
Message-ID: AANLkTi=tEhkoii7+01cXDgHrHjNp+LzSHYaknjBobQ4o@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Hey Alexander,

2010/11/20 Alexander Farber <alexander(dot)farber(at)gmail(dot)com>

> Hello,
>
> I'm trying to program a PHP-script, where users
> can rate the "goodness" of the other players:
>
> create table pref_rep (
> id varchar(32) references pref_users(id) check (id <>
> author),
> author varchar(32) references pref_users(id),
> author_ip inet,
> good boolean,
> last_rated timestamp default current_timestamp
> );
>
> To (try to) prevent tampering I'd like to delete
> entries for the same id coming
> from the same IP in the course of last hour:
>
> create or replace function pref_update_rep(_id varchar,
> _author varchar, _author_ip inet,
> _good boolean) returns void as $BODY$
> begin
>
> delete from pref_rep
> where id = _id and
> author_ip = _author_ip and
> age(to_timestamp(last_rated)) < interval '1 hour';
>
> update pref_rep set
> author = _author,
> author_ip = _author_ip,
> good = _good,
> last_rated = current_timestamp
> where id = _id and author = _author;
>
> if not found then
> insert into pref_rep(id, author, author_ip, good)
> values (_id, _author, _author_ip, _good);
> end if;
> end;
> $BODY$ language plpgsql;
>
> I have 2 questions please:
>
> 1) if I'd like to compare just the first 3 numbers of
> the IP address instead of the 4, how can I do it?
> (yes, I know about the A,B,C type of IPv4 networks...)
>
You may try something like this (this solution can be better):
SELECT (string_to_array(host('192.168.1.123'), '.'))[1:3];
to get first 3 bytes of IP in array (ready to compare with another
array).

> 2) Do I need to add an index to my table
> or are id and author indexed already?
>
Foreign keys columns does not indexed. You should create them
manually (if you need).

>
> Thank you!
> Alex
>
> --
> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-general
>

--
// Dmitriy.


From: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Re: Comparing first 3 numbers of a IPv4 address?
Date: 2010-11-20 14:44:56
Message-ID: AANLkTimLtOOKhFqdvGZn1B_pQv8Ybh8m1PQAjp=zaUJm@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

I'm actually hoping to use inet (or cidr?) instead of strings...

On 11/20/10, Dmitriy Igrishin <dmitigr(at)gmail(dot)com> wrote:
> Hey Alexander,
>
> 2010/11/20 Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
>
>> Hello,
>>
>> I'm trying to program a PHP-script, where users
>> can rate the "goodness" of the other players:
>>
>> create table pref_rep (
>> id varchar(32) references pref_users(id) check (id <>
>> author),
>> author varchar(32) references pref_users(id),
>> author_ip inet,
>> good boolean,
>> last_rated timestamp default current_timestamp
>> );
>>
>> To (try to) prevent tampering I'd like to delete
>> entries for the same id coming
>> from the same IP in the course of last hour:
>>
>> create or replace function pref_update_rep(_id varchar,
>> _author varchar, _author_ip inet,
>> _good boolean) returns void as $BODY$
>> begin
>>
>> delete from pref_rep
>> where id = _id and
>> author_ip = _author_ip and
>> age(to_timestamp(last_rated)) < interval '1 hour';
>>
>> update pref_rep set
>> author = _author,
>> author_ip = _author_ip,
>> good = _good,
>> last_rated = current_timestamp
>> where id = _id and author = _author;
>>
>> if not found then
>> insert into pref_rep(id, author, author_ip, good)
>> values (_id, _author, _author_ip, _good);
>> end if;
>> end;
>> $BODY$ language plpgsql;
>>
>> I have 2 questions please:
>>
>> 1) if I'd like to compare just the first 3 numbers of
>> the IP address instead of the 4, how can I do it?
>> (yes, I know about the A,B,C type of IPv4 networks...)
>>
> You may try something like this (this solution can be better):
> SELECT (string_to_array(host('192.168.1.123'), '.'))[1:3];
> to get first 3 bytes of IP in array (ready to compare with another
> array).
>
>
>> 2) Do I need to add an index to my table
>> or are id and author indexed already?
>>
> Foreign keys columns does not indexed. You should create them
> manually (if you need).
>
>
>>
>> Thank you!
>> Alex
>>
>> --
>> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
>> To make changes to your subscription:
>> http://www.postgresql.org/mailpref/pgsql-general
>>
>
>
>
> --
> // Dmitriy.
>

--
Sent from my mobile device


From: Dmitriy Igrishin <dmitigr(at)gmail(dot)com>
To: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Comparing first 3 numbers of a IPv4 address?
Date: 2010-11-20 14:52:11
Message-ID: AANLkTimBdnskbWbjQ6HYj_c5nzMiVzxg=-amxxgbH30P@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

You can. host() just extract IP address from a value of inet
type as text, string_to_array() converts this text to text[], and
it makes it possible to compare with another text[]... I see no
problem here. It works just fine.
But probably there is another (better) solution...

2010/11/20 Alexander Farber <alexander(dot)farber(at)gmail(dot)com>

> I'm actually hoping to use inet (or cidr?) instead of strings...
>
>
>
> On 11/20/10, Dmitriy Igrishin <dmitigr(at)gmail(dot)com> wrote:
> > Hey Alexander,
> >
> > 2010/11/20 Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
> >
> >> Hello,
> >>
> >> I'm trying to program a PHP-script, where users
> >> can rate the "goodness" of the other players:
> >>
> >> create table pref_rep (
> >> id varchar(32) references pref_users(id) check (id <>
> >> author),
> >> author varchar(32) references pref_users(id),
> >> author_ip inet,
> >> good boolean,
> >> last_rated timestamp default current_timestamp
> >> );
> >>
> >> To (try to) prevent tampering I'd like to delete
> >> entries for the same id coming
> >> from the same IP in the course of last hour:
> >>
> >> create or replace function pref_update_rep(_id varchar,
> >> _author varchar, _author_ip inet,
> >> _good boolean) returns void as $BODY$
> >> begin
> >>
> >> delete from pref_rep
> >> where id = _id and
> >> author_ip = _author_ip and
> >> age(to_timestamp(last_rated)) < interval '1 hour';
> >>
> >> update pref_rep set
> >> author = _author,
> >> author_ip = _author_ip,
> >> good = _good,
> >> last_rated = current_timestamp
> >> where id = _id and author = _author;
> >>
> >> if not found then
> >> insert into pref_rep(id, author, author_ip, good)
> >> values (_id, _author, _author_ip, _good);
> >> end if;
> >> end;
> >> $BODY$ language plpgsql;
> >>
> >> I have 2 questions please:
> >>
> >> 1) if I'd like to compare just the first 3 numbers of
> >> the IP address instead of the 4, how can I do it?
> >> (yes, I know about the A,B,C type of IPv4 networks...)
> >>
> > You may try something like this (this solution can be better):
> > SELECT (string_to_array(host('192.168.1.123'), '.'))[1:3];
> > to get first 3 bytes of IP in array (ready to compare with another
> > array).
> >
> >
> >> 2) Do I need to add an index to my table
> >> or are id and author indexed already?
> >>
> > Foreign keys columns does not indexed. You should create them
> > manually (if you need).
> >
> >
> >>
> >> Thank you!
> >> Alex
> >>
> >> --
> >> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
> >> To make changes to your subscription:
> >> http://www.postgresql.org/mailpref/pgsql-general
> >>
> >
> >
> >
> > --
> > // Dmitriy.
> >
>
> --
> Sent from my mobile device
>
> --
> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-general
>

--
// Dmitriy.


From: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Re: Comparing first 3 numbers of a IPv4 address?
Date: 2010-11-20 15:10:24
Message-ID: AANLkTindQ5pMhUztQ5kdk9YKRPQhPV9hSO=bAdK1Krm2@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

I think inet is a number internally, there is probably a more effective way...

On 11/20/10, Dmitriy Igrishin <dmitigr(at)gmail(dot)com> wrote:
> You can. host() just extract IP address from a value of inet
> type as text, string_to_array() converts this text to text[], and
> it makes it possible to compare with another text[]... I see no
> problem here. It works just fine.
> But probably there is another (better) solution...
>
> 2010/11/20 Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
>
>> I'm actually hoping to use inet (or cidr?) instead of strings...
>>
>>
>>
>> On 11/20/10, Dmitriy Igrishin <dmitigr(at)gmail(dot)com> wrote:
>> > Hey Alexander,
>> >
>> > 2010/11/20 Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
>> >
>> >> Hello,
>> >>
>> >> I'm trying to program a PHP-script, where users
>> >> can rate the "goodness" of the other players:
>> >>
>> >> create table pref_rep (
>> >> id varchar(32) references pref_users(id) check (id <>
>> >> author),
>> >> author varchar(32) references pref_users(id),
>> >> author_ip inet,
>> >> good boolean,
>> >> last_rated timestamp default current_timestamp
>> >> );
>> >>
>> >> To (try to) prevent tampering I'd like to delete
>> >> entries for the same id coming
>> >> from the same IP in the course of last hour:
>> >>
>> >> create or replace function pref_update_rep(_id varchar,
>> >> _author varchar, _author_ip inet,
>> >> _good boolean) returns void as $BODY$
>> >> begin
>> >>
>> >> delete from pref_rep
>> >> where id = _id and
>> >> author_ip = _author_ip and
>> >> age(to_timestamp(last_rated)) < interval '1 hour';
>> >>
>> >> update pref_rep set
>> >> author = _author,
>> >> author_ip = _author_ip,
>> >> good = _good,
>> >> last_rated = current_timestamp
>> >> where id = _id and author = _author;
>> >>
>> >> if not found then
>> >> insert into pref_rep(id, author, author_ip,
>> >> good)
>> >> values (_id, _author, _author_ip, _good);
>> >> end if;
>> >> end;
>> >> $BODY$ language plpgsql;
>> >>
>> >> I have 2 questions please:
>> >>
>> >> 1) if I'd like to compare just the first 3 numbers of
>> >> the IP address instead of the 4, how can I do it?
>> >> (yes, I know about the A,B,C type of IPv4 networks...)
>> >>
>> > You may try something like this (this solution can be better):
>> > SELECT (string_to_array(host('192.168.1.123'), '.'))[1:3];
>> > to get first 3 bytes of IP in array (ready to compare with another
>> > array).
>> >
>> >
>> >> 2) Do I need to add an index to my table
>> >> or are id and author indexed already?
>> >>
>> > Foreign keys columns does not indexed. You should create them
>> > manually (if you need).
>> >
>> >
>> >>
>> >> Thank you!
>> >> Alex
>> >>
>> >> --
>> >> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
>> >> To make changes to your subscription:
>> >> http://www.postgresql.org/mailpref/pgsql-general
>> >>
>> >
>> >
>> >
>> > --
>> > // Dmitriy.
>> >
>>
>> --
>> Sent from my mobile device
>>
>> --
>> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
>> To make changes to your subscription:
>> http://www.postgresql.org/mailpref/pgsql-general
>>
>
>
>
> --
> // Dmitriy.
>

--
Sent from my mobile device


From: Dmitriy Igrishin <dmitigr(at)gmail(dot)com>
To: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Comparing first 3 numbers of a IPv4 address?
Date: 2010-11-20 15:19:25
Message-ID: AANLkTinVPQW8xE+RSSwhzM1RY8TaUKaUnixwm6F5Xen4@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

I will be glad to see the best solution, so if you find it please share. :-)

But you want to compare IP addresses by 3 first parts. I don't see any
function or operator at SQL level which allow to do it without converting
to text.
Probably, you can do it by manipulating a binary form (from libpq).
But is it worth it ? :-)

2010/11/20 Alexander Farber <alexander(dot)farber(at)gmail(dot)com>

> I think inet is a number internally, there is probably a more effective
> way...
>
> On 11/20/10, Dmitriy Igrishin <dmitigr(at)gmail(dot)com> wrote:
> > You can. host() just extract IP address from a value of inet
> > type as text, string_to_array() converts this text to text[], and
> > it makes it possible to compare with another text[]... I see no
> > problem here. It works just fine.
> > But probably there is another (better) solution...
> >
> > 2010/11/20 Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
> >
> >> I'm actually hoping to use inet (or cidr?) instead of strings...
> >>
> >>
> >>
> >> On 11/20/10, Dmitriy Igrishin <dmitigr(at)gmail(dot)com> wrote:
> >> > Hey Alexander,
> >> >
> >> > 2010/11/20 Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
> >> >
> >> >> Hello,
> >> >>
> >> >> I'm trying to program a PHP-script, where users
> >> >> can rate the "goodness" of the other players:
> >> >>
> >> >> create table pref_rep (
> >> >> id varchar(32) references pref_users(id) check (id <>
> >> >> author),
> >> >> author varchar(32) references pref_users(id),
> >> >> author_ip inet,
> >> >> good boolean,
> >> >> last_rated timestamp default current_timestamp
> >> >> );
> >> >>
> >> >> To (try to) prevent tampering I'd like to delete
> >> >> entries for the same id coming
> >> >> from the same IP in the course of last hour:
> >> >>
> >> >> create or replace function pref_update_rep(_id varchar,
> >> >> _author varchar, _author_ip inet,
> >> >> _good boolean) returns void as $BODY$
> >> >> begin
> >> >>
> >> >> delete from pref_rep
> >> >> where id = _id and
> >> >> author_ip = _author_ip and
> >> >> age(to_timestamp(last_rated)) < interval '1 hour';
> >> >>
> >> >> update pref_rep set
> >> >> author = _author,
> >> >> author_ip = _author_ip,
> >> >> good = _good,
> >> >> last_rated = current_timestamp
> >> >> where id = _id and author = _author;
> >> >>
> >> >> if not found then
> >> >> insert into pref_rep(id, author, author_ip,
> >> >> good)
> >> >> values (_id, _author, _author_ip, _good);
> >> >> end if;
> >> >> end;
> >> >> $BODY$ language plpgsql;
> >> >>
> >> >> I have 2 questions please:
> >> >>
> >> >> 1) if I'd like to compare just the first 3 numbers of
> >> >> the IP address instead of the 4, how can I do it?
> >> >> (yes, I know about the A,B,C type of IPv4 networks...)
> >> >>
> >> > You may try something like this (this solution can be better):
> >> > SELECT (string_to_array(host('192.168.1.123'), '.'))[1:3];
> >> > to get first 3 bytes of IP in array (ready to compare with another
> >> > array).
> >> >
> >> >
> >> >> 2) Do I need to add an index to my table
> >> >> or are id and author indexed already?
> >> >>
> >> > Foreign keys columns does not indexed. You should create them
> >> > manually (if you need).
> >> >
> >> >
> >> >>
> >> >> Thank you!
> >> >> Alex
> >> >>
> >> >> --
> >> >> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
> >> >> To make changes to your subscription:
> >> >> http://www.postgresql.org/mailpref/pgsql-general
> >> >>
> >> >
> >> >
> >> >
> >> > --
> >> > // Dmitriy.
> >> >
> >>
> >> --
> >> Sent from my mobile device
> >>
> >> --
> >> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
> >> To make changes to your subscription:
> >> http://www.postgresql.org/mailpref/pgsql-general
> >>
> >
> >
> >
> > --
> > // Dmitriy.
> >
>
> --
> Sent from my mobile device
>
> --
> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-general
>

--
// Dmitriy.


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Comparing first 3 numbers of a IPv4 address?
Date: 2010-11-20 15:47:31
Message-ID: 28036.1290268051@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Alexander Farber <alexander(dot)farber(at)gmail(dot)com> writes:
> 1) if I'd like to compare just the first 3 numbers of
> the IP address instead of the 4, how can I do it?

regression=# select network(set_masklen('123.45.67.42'::inet, 24)) =
regression-# network(set_masklen('123.45.67.56'::inet, 24));
?column?
----------
t
(1 row)

regards, tom lane


From: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Re: Comparing first 3 numbers of a IPv4 address?
Date: 2010-11-20 16:27:51
Message-ID: AANLkTikm_1+5+nG7vVX5wWZB6dONcTuSw_99Mi9jO66m@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Thank you. Or maybe also?

(author_ip & '255.255.255.0'::inet) = (_author_ip & '255.255.255.0'::inet)

On Sat, Nov 20, 2010 at 4:47 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> Alexander Farber <alexander(dot)farber(at)gmail(dot)com> writes:
>> 1) if I'd like to compare just the first 3 numbers of
>> the IP address instead of the 4, how can I do it?
>
> regression=# select network(set_masklen('123.45.67.42'::inet, 24)) =
> regression-#  network(set_masklen('123.45.67.56'::inet, 24));
>  ?column?
> ----------
>  t
> (1 row)
>|


From: Dmitriy Igrishin <dmitigr(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Alexander Farber <alexander(dot)farber(at)gmail(dot)com>, pgsql-general(at)postgresql(dot)org
Subject: Re: Comparing first 3 numbers of a IPv4 address?
Date: 2010-11-20 21:34:56
Message-ID: AANLkTimOFhgrR7EmUEMTqtHgUShUi9MbY-SMvFNmDKcu@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Hey Tom,

Thanks for you solution!

2010/11/20 Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>

> Alexander Farber <alexander(dot)farber(at)gmail(dot)com> writes:
> > 1) if I'd like to compare just the first 3 numbers of
> > the IP address instead of the 4, how can I do it?
>
> regression=# select network(set_masklen('123.45.67.42'::inet, 24)) =
> regression-# network(set_masklen('123.45.67.56'::inet, 24));
> ?column?
> ----------
> t
> (1 row)
>
>
> regards, tom lane
>
> --
> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-general
>

--
// Dmitriy.


From: Jasen Betts <jasen(at)xnet(dot)co(dot)nz>
To: pgsql-general(at)postgresql(dot)org
Subject: Re: Comparing first 3 numbers of a IPv4 address?
Date: 2010-11-30 18:33:13
Message-ID: id3g19$ipe$1@reversiblemaps.ath.cx
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

On 2010-11-20, Alexander Farber <alexander(dot)farber(at)gmail(dot)com> wrote:

>
> 1) if I'd like to compare just the first 3 numbers of
> the IP address instead of the 4, how can I do it?
> (yes, I know about the A,B,C type of IPv4 networks...)

have you heard of CIDR (what about IPV6, which I'm going to ignore,
but you should consider unless this code is throw-away)

just use set_masklen and the >> operator.

select set_masklen('1.2.3.4'::inet,24) >> '1.2.3.244'::inet;

--
⚂⚃ 100% natural