PostgreSQL:比较 IPv4 地址的前 3 个数字?

发布于 2024-10-03 11:36:59 字数 1489 浏览 5 评论 0原文

我正在尝试编写一个 PHP 脚本,其中用户 可以评价其他用户的“善良”:

   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
   );

为了(尝试)防止篡改,我想删除 在过去一小时内来自同一 IP 的相同 ID 的条目

(由于代理/路由器而偶尔出现误报是可以的 - 因为失去评级是可以的,因为作者可以随时重新提交时间;但是让一些白痴在不同的 ID 下注册并在我离开网站时破坏我的整个数据库是不行的):

   /* _author_ip will be $_SERVER['REMOTE_ADDR'] */
   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;

我有两个问题:

1)如果我只想比较的前 3 个数字 IP 地址而不是 4,我该怎么办? (是的,我知道 IPv4 网络的 A、B、C 类型,这里并不重要...)

2)我需要在表中添加索引吗 或者 id 和作者已经编入索引了吗?

谢谢你! 亚历克斯

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

   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 during the course of last hour

(occasional false positives because of proxies/routers are ok - because it's ok to lose a rating, since the author can re-submit it at any later time; but it's not ok to have some idiot registered under different id's and spoiling my whole database while I'm away from the web site):

   /* _author_ip will be $_SERVER['REMOTE_ADDR'] */
   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 types of IPv4 networks, doesn't matter here...)

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

Thank you!
Alex

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

水波映月 2024-10-10 11:36:59

1)您可以使用 &接线员:

postgres=# SELECT '1.2.3.4'::inet & '255.255.255.0'::inet;
 ?column?
----------
 1.2.3.0
(1 row)

所以,你可以比较

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

2) 我不知道,是吗?

1) You can use the & operator:

postgres=# SELECT '1.2.3.4'::inet & '255.255.255.0'::inet;
 ?column?
----------
 1.2.3.0
(1 row)

So, you can compare

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

2) I don't know, are they?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文