C#实现Punycode编码/解码

news2024/11/25 11:44:30
测试代码
string word = "我爱你";
string idn = "我爱你.中国";
string wordCode = PunyCode.Encode(word);
string punycode = PunyCode.IDN2Punycode(idn);

Console.WriteLine(word);
Console.WriteLine(wordCode);
Console.WriteLine(PunyCode.Decode(wordCode));

Console.WriteLine();

Console.WriteLine(idn);
Console.WriteLine(punycode);
Console.WriteLine(PunyCode.Punycode2IDN(punycode));
输出
我爱你
6qq986b3xl
我爱你

我爱你.中国
xn--6qq986b3xl.xn--fiqs8s
我爱你.中国
源码
using System;
using System.Text;
using System.Text.RegularExpressions;

public class PunyCode
{
    public static string IDN2Punycode(string input)
    {
        string[] spli = new string[] { "." };
        string[] inputArray = input.Split(spli, StringSplitOptions.RemoveEmptyEntries);
        string retstr = "";
        for (int i = 0; i < inputArray.Length; i++)
        {
            Regex myreg = new Regex("^[0-9a-zA-Z\\-]+$");
            if (myreg.IsMatch(inputArray[i]))
                retstr += inputArray[i] + ".";
            else
                retstr += "xn--" + Encode(inputArray[i]) + ".";
        }

        return retstr.TrimEnd('.');
    }
    public static string Punycode2IDN(string input)
    {
        string[] spli = new string[] { "." };
        string[] inputArray = input.ToLower().Split(spli, StringSplitOptions.RemoveEmptyEntries);
        string retstr = "";
        for (int i = 0; i < inputArray.Length; i++)
        {
            string tmp = inputArray[i];
            if (tmp.StartsWith("xn--"))
                retstr += Decode(tmp.Substring(4)) + ".";
            else
                retstr += tmp + ".";
        }

        return retstr.TrimEnd('.');
    }
    public static string Encode(string input)
    {
        int n = 0x80;
        int delta = 0;
        int bias = 72;
        StringBuilder output = new StringBuilder();
        int b = 0;
        for (int i = 0; i < input.Length; i++)
        {
            char c = input[i];
            if (c < 0x80)
            {
                output.Append(c);
                b++;
            }
        }

        if (b > 0) output.Append('-');

        int h = b;
        while (h < input.Length)
        {
            int m = int.MaxValue;

            for (int i = 0; i < input.Length; i++)
            {
                int c = input[i];
                if (c >= n && c < m) m = c;
            }

            if (m - n > (int.MaxValue - delta) / (h + 1)) throw new Exception();

            delta += (m - n) * (h + 1);
            n = m;

            for (int j = 0; j < input.Length; j++)
            {
                int c = input[j];
                if (c < n)
                {
                    delta++;
                    if (0 == delta) throw new Exception();
                }
                if (c == n)
                {
                    int q = delta;

                    for (int k = 36; ; k += 36)
                    {
                        int t;
                        if (k <= bias) t = 1;
                        else if (k >= bias + 26) t = 26;
                        else t = k - bias;

                        if (q < t) break;

                        output.Append((char)Digit2Codepoint(t + (q - t) % (36 - t)));
                        q = (q - t) / (36 - t);
                    }

                    output.Append((char)Digit2Codepoint(q));
                    bias = Adapt(delta, h + 1, h == b);
                    delta = 0;
                    h++;
                }
            }

            delta++;
            n++;
        }

        return output.ToString();
    }

    public static string Decode(string input)
    {
        int n = 0x80;
        int i = 0;
        int bias = 72;
        StringBuilder output = new StringBuilder();

        int d = input.LastIndexOf('-');
        if (d > 0)
        {
            for (int j = 0; j < d; j++)
            {
                char c = input[j];
                if (c >= 0x80) throw new Exception();
                output.Append(c);
            }
            d++;
        }
        else d = 0;

        while (d < input.Length)
        {
            int oldi = i;
            int w = 1;

            for (int k = 36; ; k += 36)
            {
                if (d == input.Length) throw new Exception();

                int c = input[d++];
                int digit = Codepoint2Digit(c);
                if (digit > (int.MaxValue - i) / w) throw new Exception();

                i += digit * w;

                int t;
                if (k <= bias) t = 1;
                else if (k >= bias + 26) t = 26;
                else t = k - bias;

                if (digit < t) break;

                w *= 36 - t;
            }

            bias = Adapt(i - oldi, output.Length + 1, oldi == 0);

            if (i / (output.Length + 1) > int.MaxValue - n) throw new Exception();

            n += i / (output.Length + 1);
            i %= output.Length + 1;
            output.Insert(i, (char)n);
            i++;
        }
        return output.ToString();
    }

    private static int Adapt(int delta, int numpoints, bool first)
    {
        delta /= first ? 700 : 2;

        delta += delta / numpoints;

        int k = 0;
        while (delta > 455)
        {
            delta /= 35;
            k += 36;
        }

        return k + (36 * delta) / (delta + 38);
    }

    private static int Digit2Codepoint(int d)
    {

        if (d < 26) return d + 97;

        if (d < 36) return d + 22;

        throw new Exception();

    }

    private static int Codepoint2Digit(int c)
    {

        if (c < 58) return c - 22;

        if (c < 123) return c - 97;

        throw new Exception();
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2210834.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【工欲善其事】巧用 PowerShell 自动清除复制 PDF 文本时夹杂的换行符号

文章目录 巧用 PowerShell 自动清除复制 PDF 文本时夹杂的换行符号1 问题描述2 解决方案3 具体步骤4 效果测试5 小结与复盘 巧用 PowerShell 自动清除复制 PDF 文本时夹杂的换行符号 1 问题描述 不知各位是否也为复制过来的文本中夹杂的回车换行符抓狂过&#xff1f;就是在复…

Spring Boot知识管理:提升信息检索效率

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…

ubuntu下route命令详解

buntu下route命令详解 1、显示路由表 route -n2、临时路由设置&#xff0c;重启网卡失效#添加一条路由(发往192.168.62这个网段的全部要经过网关192.168.1.1)route add -net 192.168.62.0 netmask 255.255.255.0 gw 192.168.1.1#删除一条路由 删除的时候不用写网关route del …

extern “C“ 的作用、C++ 和 C 编译的不同、C++ 编译过程的五个主要阶段

在 C 中&#xff0c;如果需要从 C 语言导入函数或与 C 代码交互&#xff0c;需要使用 extern "C" 关键字。这是因为 C 和 C 在编译过程中的 符号命名机制&#xff08;即 "名称修饰" 或 "name mangling"&#xff09;不同。 1. extern "C&qu…

怎么把一段音频的人声和背景音乐分开?

在数字音频处理中&#xff0c;将一段音频中的人声和背景音乐分开是一个复杂但又常见的需求。这种技术广泛应用于音乐制作、影视后期、广告制作等多个领域。本文将为你详细解析如何通过不同的方法实现这一目标&#xff0c;帮助你更好地掌握音频分离技术。 一、音频分离的基本概念…

无人直播自动化回复客户咨询

我们插件是根据页面元素变动进行自动化操作的&#xff0c;想要实现网页版自动化&#xff0c;必须了解html以及dom结构&#xff0c;还有xpath定位方法。 各大直播后台页面结构不一样&#xff0c;所以要进行兼容处理&#xff0c;我们一个插件支持以下直播或客服平台 唯一客服浏…

数据结构与算法:栈与队列的高级应用

目录 3.1 栈的高级用法 3.2 队列的深度应用 3.3 栈与队列的综合应用 总结 数据结构与算法&#xff1a;栈与队列的高级应用 栈和队列是两种重要的线性数据结构&#xff0c;它们在计算机科学和工程的许多领域都有广泛的应用。从函数调用到表达式求值&#xff0c;再到任务调度…

c#的opcua客户端源码,支持用户名密码

在工作中遇到需要采集西门子机床的opcua和kepServer的opcua&#xff0c;找了一些网上的demo都不能都连接成功&#xff0c;好不容易找到一个两个都支持的c#opcua客户端源码&#xff0c;分享给大家。 软件界面如下 连接kepserver成功的界面 连接西门子opcua的界面 c#源码链接如下…

开关电源调制模式和工作模式

开关电源调制模式和工作模式 ‌‌开关电源定义开关电源分类‌单管DC/DC和、双管DC/DC和四管DC/DC的主要区别正激和反激 DCDCBUCK原理BOOST原理BUCK-BOOST原理异步整流和异步整流同步整流异步整流同步和异步整流区别同步和异步整流优缺点 DCDC调制模式PWM&#xff08;Pulse Widt…

C++ | Leetcode C++题解之第475题供暖器

题目&#xff1a; 题解&#xff1a; class Solution { public:int findRadius(vector<int>& houses, vector<int>& heaters) {sort(houses.begin(), houses.end());sort(heaters.begin(), heaters.end());int ans 0;for (int i 0, j 0; i < houses.…

轻松掌握TCP与UDP核心机制

White graces&#xff1a;个人主页 &#x1f649;专栏推荐:Java入门知识&#x1f649; &#x1f649; 内容推荐:网络编程TCP&#x1f649; &#x1f439;今日诗词:Best wishes&#x1f439; ⛳️点赞 ☀️收藏⭐️关注&#x1f4ac;卑微小博主&#x1f64f; ⛳️点赞 ☀️收…

相机曝光的两种模式

相机的曝光模式 相机帧率和曝光时间的关系 相机的图像采集包括曝光(Exposure)和读出(Readout)两部分 曝光又分为非重叠(non-overlapped)曝光和重叠(overlapped)曝光两种 在非重叠(“non-overlapped”)模式中&#xff0c;每个图像采集的周期中&#xff0c;相机在下一个图像采集…

萝卜快跑:迈向全球,挑战与机遇并存

萝卜快跑&#xff1a;迈向全球&#xff0c;挑战与机遇并存 引言 萝卜快跑的崛起 萝卜快跑的优势 萝卜快跑面临的挑战 未来展望 引言 在当今科技飞速发展的时代&#xff0c;自动驾驶技术成为了全球瞩目的焦点。众多科技巨头纷纷投入大量资源&#xff0c;试图在这个新兴领域…

文件完整性监控:如何提高企业的数据安全性

企业网络庞大而复杂&#xff0c;需要处理大量关键业务数据&#xff0c;这些敏感文件在企业网络中不断传输&#xff0c;并由多个用户和实体存储、共享和访问。FIM 工具或具有 FIM 功能的 SIEM 解决方案使企业能够跟踪未经授权的文件更改、对敏感信息的恶意访问、数据篡改尝试和内…

FreeRTOS——空闲任务和钩子函数介绍

空闲任务 在前面的学习中我们提到&#xff0c;空闲任务会负责释放一些被删除任务的内存&#xff0c;在FreeRTOS中&#xff0c;用户分配的内存通常也是在空闲任务中释放的。空闲任务是一个特殊的任务&#xff0c;当没有其他任务需要运行时&#xff0c;系统将会调度空闲任务来执行…

硬盘格式化后能恢复数据吗?好用4款工具集锦

嘿&#xff0c;硬盘格式化后能恢复数据吗&#xff1f;咱们现在的生活&#xff0c;数据可是宝贝&#xff0c;这大家都清楚。学习用的资料、工作的文件&#xff0c;还有那些宝贵的照片、视频&#xff0c;统统都存硬盘里。万一硬盘不小心被格式化了&#xff0c;那感觉就像所有东西…

【GUI】使用 PySide6 开发图片左右切换软件

使用 PySide6 开发图片左右切换软件 前言 在现代软件开发中&#xff0c;使用 Python 开发跨平台的 GUI 应用程序变得非常普遍。今天&#xff0c;我们将使用 PySide6 来开发一个简单的图片浏览器&#xff0c;它可以实现图片左右切换的功能&#xff0c;并自适应按钮布局。本教程…

闭着眼学机器学习——朴素贝叶斯分类

引言&#xff1a; 在正文开始之前&#xff0c;首先给大家介绍一个不错的人工智能学习教程&#xff1a;https://www.captainbed.cn/bbs。其中包含了机器学习、深度学习、强化学习等系列教程&#xff0c;感兴趣的读者可以自行查阅。 1. 算法介绍 朴素贝叶斯是一种基于贝叶斯定理…

c++应用网络编程之十一Linux下的epoll模式基础

一、epoll模式 在前面分析了select和poll两种IO多路复用的模式&#xff0c;但总体给人的感觉有一种力不从心的感觉。尤其是刚刚接触底层网络开发的程序员&#xff0c;被很多双十一千万并发&#xff0c;游戏百万并发等等已经给唬的一楞一楞的。一听说只支持一两千个并发&#x…

YOLOv9分割改进 ,YOLOv9分割改进主干网络为华为EfficientNet,助力涨点

YOLOv9 分割改进前训练结果: YOLOv9 分割改进后训练结果: 摘要 卷积神经网络(ConvNets)通常在固定的资源预算下开发,然后在有更多资源时进行扩展以提高准确性。在本文中,我们系统地研究了模型扩展,并发现仔细平衡网络深度、宽度和分辨率可以带来更好的性能。基于这一…