ipv4与ipv6如何转换
IPv4:是互联网协议的第四版,同时也是第一个被广泛使用,构成现今互联网技术的基石的协议;IPv6:是互联网工程任务组设计的用于替代现行版本IPv4的下一代IP协议;目前IP协议的版本号是IPv4,它的下一个版本就是IPv6。ipv4与ipv6地址如何转换的python解决办法源码如下:(需要用到twisted.python.compat及struct和python socket方法)import struct,socket#import twisted.python.compat #导入twisted.python.compat 更方便# ipv4数字地址def ipv4_to_string(ipv4):ipv4_n = socket.htonl(ipv4)data = struct.pack('I', ipv4_n)ipv4_string = socket.inet_ntop(socket.AF_INET, data)return ipv4_stringdef ipv4_from_string(ipv4_string):data = socket.inet_pton(socket.AF_INET, ipv4_string)ipv4_n = struct.unpack('I', data)ipv4 = socket.ntohl(ipv4_n[0])return ipv4def ipv4_readable2int(ipv4):return int(ipv4)def ipv4_int2readable(ipv4):return str(ipv4)# ipv6用四个整数(tuple或用,分开的字符串)表示def ipv6_to_string(ipv6):ipv6_n = (socket.htonl(ipv6[0]),socket.htonl(ipv6[1]),socket.htonl(ipv6[2]),socket.htonl(ipv6[3]))data = struct.pack('IIII', ipv6_n[0], ipv6_n[1], ipv6_n[2], ipv6_n[3])ipv6_string = socket.inet_ntop(socket.AF_INET6, data)return ipv6_stringdef ipv6_from_string(ipv6_string):data = socket.inet_pton(socket.AF_INET6, ipv6_string)ipv6_n = struct.unpack('IIII', data)ipv6 = (socket.ntohl(ipv6_n[0]),socket.ntohl(ipv6_n[1]),socket.ntohl(ipv6_n[2]),socket.ntohl(ipv6_n[3]))return ipv6def ipv6_tuple2readable(ipv6):return str(ipv6[0]) + ',' + str(ipv6[1]) + ',' + str(ipv6[2]) + ',' + str(ipv6[3])def ipv6_readable2tuple(ipv6):return tuple(ipv6.split(','))#win32 下实现 inet_pton 和 inet_ntodef inet_ntop(family, ipstr):if family== socket.AF_INET:return socket.inet_ntoa(ipstr)elif family== socket.AF_INET6:v6addr = ':'.join(('%02X%02X' % (ord(i), ord(j)))for i,j in zip(ipstr[::2], ipstr[1::2]))return v6addr#www.iplaypy.comdef inet_pton(family, addr):if family== socket.AF_INET:return socket.inet_aton(addr)elif family== socket.AF_INET6:if '.' in addr: # a v4 addrv4addr = addr[addr.rindex(':')+1:]v4addr = socket.inet_aton(v4addr)v4addr = map(lambda x: ('%02X' % ord(x)), v4addr)v4addr.insert(2, ':')newaddr = addr[:addr.rindex(':')+1] + ''.join(v4addr)return inet_pton(family, newaddr)dbyts = [0]* 8 # 8 groupsgrps = addr.split(':')for i,v in enumerate(grps):if v:dbyts[i] = int(v, 16)else:for j, w in enumerate(grps[::-1]):if w:dbyts[7-j] = int(w, 16)else:breakbreakreturn ''.join( (chr(i//256) + chr(i%256)) for i in dbyts)else:raise RuntimeError("What family?")IPv4的地址如何转换为IPv6的地址IPv4地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节),通常我们以10进制表示。例如192.168.1.1就是一个10进制的IPv4地址,如果用2进制表示,则为11000000 10101000 00000001 00000001这里设计的2进制与10进制的计算方法比较简单,这里就不再阐述。那么由IPv4的地址转换为IPv6的地址怎么转换呢?这里有2种表示方法:第一种比较简单的。例如还是IPv4的192.168.1.1 转换成IPv6的地址,则为::192.168.1.1 。就是在IPv4的地址前添加::即可,不需要经过计算。第二种标准的IPv6地址,需要经过计算。首先,需要将IPv4的地址转换成2进制的,然后再由2进制的数,每4位为一组,转换成16进制的,最后再转换为IPv6地址。举例说明,192.168.1.1,10进制表示为192.168.1.1,2进制表示为11000000 10101000 00000001 00000001,16进制表示为C0 A8 01 01,IPv6地址为0:0:0:0:0:0:C0A8:0101。下表会更加清晰。
这个很好解决。 以下都以 ipv4 的 192.168.0.199为例最简单的兼容地址就是::192.168.0.199我估计你想问的是下面的写法::C0A8:00C7我们知道 ipv4的地址是32位二进制用点分十进制表示。而ipv6的地址是128位二进制 通常用8组16进制数表示想要写出兼容的ipv6地址。 只需要 把32位的ipv4地址 转化成十六进制写法就可以了也就是说 前面96位都是0 后面32位用ipv4的地址表示出来就可以。::表示全是零C0就是192的十六进制写法 A8就是168的十六进制写法。ipv4地址每组之间用的点表示。ipv6用的是冒号表示。 希望你能明白
IPv6隧道技术

IPV4升级IPV6的步骤
IPV4是无法升级IPV6。原因:Ipv4和ipv6不需要进行转换,因为为了实现Ipv4-ipv6互操作,Ipv4地址嵌入在ipv6地址中,通常表示为:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:X:d.d.d.d。第一个96b用十六进制表示,最后一个32b用spot-decimalIpv4表示。计算:直接截取ipv6的最后32b作为ipv4。扩展资料:IPv6和IPv4之间的过渡IPv6不能立即取代IPv4,因此在的IPv4和IPv6在一段时间内会存在于一个环境中。一个好的转换机制需要提供一个平稳的转换过程,对现有用户的影响最小。这个主题是IETF ngtrans工作组的主要目标,许多转换机制已经被提出,其中一些已经在6Bone上使用。IETF推荐双栈、隧道和网络地址转换机制:一、IPv6/IPv4双栈技术二、隧道技术三、网络地址转换器(NAT)技术将IPv4和IPv6地址视为内部和全局地址,反之亦然。例如,当内部IPv4主机希望与外部IPv6主机通信时,NAT服务器将IPv4地址(相当于内部地址)转换为IPv6地址(相当于全局地址),服务器将维护一个IPv4和IPv6地址的映射表。相反,当内部IPv6主机与外部IPv4主机通信时,IPv6主机映射到内部地址,IPv4主机映射到全局地址。NAT技术可以解决IPv4主机和IPv6主机之间的互联问题。
安装IPV6 的步骤: XP下的配置方法与2003下配置方法基本相同。只是XP下必须先安装上IPV6协议,并且至少升级至SP1。配置过程如下:1、安装IPV6协议C:>ipv6 install2 、查看端口信息首先使用 ipv6 if 指令查看各接口状态,一般情况下,你会看到如下显示:Interface 4 (site 1): 本地连接……Interface 3 (site 1): 6-over-4 Virtual Interface……Interface 2 (site 0): Tunnel Pseudo-Interface……Interface 1 (site 0): Loopback Pseudo-Interface……Interface 4 是本地的实际端口,其他三个都是虚拟端口,值得注意的是 Interface 2 ,它是 Auto-Tunnel 的端口,在接入配置中我们要用到。3、如果是在纯IPV6网络(或IPV6和IPV4双栈网络)中,你就可以自动获得IPV6地址,可以访问IPV6网站了。你也可以设置固定的IPV6地址,方法如下:C:>netshnetsh>interface ipv6netsh interface ipv6>add address "本地连接" fe80:a520:1314::1/* 设定固定的IPv6地址,“本地连接”是指你的机上建立的某个连接的名称 */netsh interface ipv6>add dns "本地连接" 2001:251:e101:0::2/* 设定IPv6 DNS地址 */4、如果你是在IPV4网络中,你需要与IPV6网络进行隧道连结。需要对端用户的配合来建立隧道,对端可以是网络中心的路由(交换)器,也可以是另一台PC机。无论如何,以下信息都是必须的:。你的可路由到对端的IPV4地址,假定为 210.35.168.100。对端的IPV4地址,假定为 210.35.240.24。对端的IPV6地址,假定为 2001:250:6C01:1000:1。对端分配给你的IPV6地址,假设为 2001:250:6C01:1000:2本端配置如下:配置隧道: ipv6 ifcr v6v4 210.35.168.100210.35.240.24为本机配置 ipv6 地址: ipv6 adu 4/2001:250:6c01:100:3、注: 第4个Interface端口的地址设为2001:250:6c01:100::2,这种配置的时候,一般指定为实际存在的Interface号,如果只有一块网卡的话,应该是4号Interface。 */为本机配置路由: ipv6 rtu ::/04、2001:250:6c01:100::1对端(服务端)如果是网络中心,请看路由器配置。如果对端也是PC机,根据系统不同,按本站所列各操作系统的配置方法配置。5、如果要用WindowsXP做路由器, 则还需要打开其他接口的转发功能. 例如, 如果接口4是你的网卡, 你所在的局域网就是挂在这块网卡下的, 那么你还需要打开它的转发功能: ipv6 ifc 4 forwards 根据需要,你可能还愿意打开某些接口的路由广播功能
IPv6升级不是随便设置一下就可以的,里面涉及很多技术和网络安全问题,还是要用到专业的技术,现在有很多公司都能做IPv6升级,像Dr.COM城市热点,可以去了解下。

IPV4与IPV6如何转换
这个很好解决。 以下都以ipv4的192.168.0.199为例最简单的兼容地址就是::192.168.0.199我估计你想问的是下面的写法::C0A8:00C7我们知道ipv4的地址是32位二进制用点分十进制表示。而ipv6的地址是128位二进制通常用8组16进制数表示想要写出兼容的ipv6地址。只需要把32位的ipv4地址转化成十六进制写法就可以了也就是说前面96位都是0后面32位用ipv4的地址表示出来就可以。::表示全是零C0就是192的十六进制写法A8就是168的十六进制写法。ipv4地址每组之间用的点表示。ipv6用的是冒号表示。 希望你能明白
IPv6的地址格式与IPv4不同。一个IPv6的IP地址由8个地址节组成,每节包含16个地址位,以4个十六进制数书写,节与节 兼容IPv4的IPv6地址是一种特殊的IPv6单点广播地址,一个IPv6节点与一个IPv4节点可以使用这种地址在IPv4网络中通信。这种地址是由96个0位加上32位IPv4地址组成的,例如,假设某节点的IPv4地址是192.56.1.1,那么兼容IPv4的IPv6地址就是0:0:0:0:0:0:C038:101

IPv4转换为IPv6
IPv4和ipv6是完全不同的两种概念,是没有转换关系的,下面是我从网上找来的 一、 IPv6 地址的表示形式用文本方式表示的 IPv6 地址有三种规范的形式:1 )优先选用的形式是 X:X:X:X:X:X:X:X ,其中 X 是 8 个 16 位地址段的十六进制值。例如:FEDC:BA98:7654:4210:FEDC:BA98:7654:32102001:0:0:0:0:8:800:201C:417A每一组数值前面的 0 可以省略。如 0008 写成 8 。2 )在分配某种形式的 IPv6 地址时,会发生包含长串 0 位的地址。为了简化包含 0 位地址的书写,可以使用 “::” 符号简化多个 0 位的 16 位组。 “::” 符号在一个地址中只能出现一次。该符号也可以用来压缩地址中前部和尾部的 0 。举例如下:FF01:0:0:0:0:0:0:101 多点传送地址0:0:0:0:0:0:0:1 回送地址0:0:0:0:0:0:0:0 未指定地址可用下面的压缩形式表示:1080::8:800:200C:417A 单点传送地址FF01::101 多点传送地址::1 回送地址:: 未指定地址3 )在涉及 IPv4 和 IPv6 节点混合的这样一个节点环境的时候,有时需要采用另一种表达方式,即 X:X:X:X:X:X:D.D.D.D ,其中 X 是地址中 6 个高阶 16 位段的十六进制值, D 是地址中 4 个低阶 8 位字段的十进制值(按照 IPv4 标准表示)。例如:下面两种嵌入 IPv4 地址的 IPv6 地址(见本节后面)。0:0:0:0:0:0:202.201.32.29 嵌入 IPv4 地址的 IPv6 地址 0:0:0:0:0:FFFF:202.201.32.30 嵌入 IPv4 地址的 IPv6 地址写成压缩形式为:::202.201.32.29::FFFF.202.201.32.30上面的表达形式,在实际中经常用到,尤其是压缩简化的形式。二、地址空间IPv4 与 IPv6 地址最大的差别在于长度: IPv4 地址长度是 32 位,而 IPv6 的地址长度是 128 位。这样 IPv6 就可以有 2128 个地址,大约的数目是 1018 个,准确的数字是 [i]340,282,366,920,938,463,374,607,431,768,211,456 。这样的地址长度,即使考虑到以后向其他星球移民也够用了。一个典型的 IPv6 地址由地址中的起始的多位表明,由这些起始报头位组成的可变长度域被称为格式前缀( Format Prefix , FP )。根据这些格式前缀所做的地址分配如图一个典型的 IPv6 地址由地址中的起始的多位表明,由这些起始报头位组成的可变长度域被称为格式前缀( Format Prefix , FP )。根据这些格式前缀所做的地址分配如图 分 配 前缀(二进制) 占地址空间的比例保留 未分配 为 NSAP 分配保留 为 IPX 分配保留 未分配 未分配 未分配 可聚集全球单点传送(单播)地址 未分配 未分配 未分配 未分配 未分配 未分配 未分配 未分配 未分配 未分配 链路本地单点传送(单播)地址 站点本地单点传送(单播)地址 组播(多点传送)地址 0000 0000 0000 0001 0000 001 0000 010 0000 0011 0000 1 0001 001 010 011 100 101 110 1110 1111 0 1111 10 1111 110 1111 1110 0 1111 1110 10 1111 1110 11 1111 1111 1/256 1/256 1/128 1/128 1/128 1/32 1/16 1/8 1/8 1/8 1/8 1/8 1/8 1/16 1/32 1/64 1/128 1/512 1/1024 1/1024 1/256我们可以看到, IPv6 最初只使用了大约 15 %的地址空间,其余的地址空间留做将来使用。值得注意的是保留地址和未分配地址是不一样的,保留地址占地址空间的 1/256 ( FP = 0000 0000 ),是用做非指定地址、回送地址、和嵌入 IPv4 地址的 IPv6 地址。这几种地址的详情见本节后面以及本文的实验数据部分。其它的保留地址是 NSAP 地址( FP = 0000 001 ),可以从 ISO/OSI 网络服务访问点 [i] ( Network Service Access Point , NSAP )中获得。同样, IPX 地址也保留下来( FP = 0000 010 ),这些地址可以从 Novell IPX [ii] (见参考文献 19 的 4.6.10 节)地址获得。除了多点传送地址( FP = 1111 1111 ),格式前缀从 001 到 111 都需要 EUI64 [iii] 格式中具有 64 位的接口标识符。三、地址类型IPv6 中地址有三种类型:单点传送( Unicast )、多点传送( Multicast )、任意点传送( Anycast )。也有文献称之为单播、组播、泛播地址。 IPv6 中不再有象 IPv4 中那样的广播( broadcast )地址,它的功能由多点传送地址来实现。l 单点传送地址:一个单接口标识符,送往单点传送地址的包将被传送到该地址所标识的接口上。2 任意点传送地址:一组接口(一般不属于不同节点)的标识符。送往一个任意点传送地址的包将被传送到该地址所标识的接口之一(根据路由协议中的距离的计算方法而确定的 “ 最近 ” 的一个)。 3 多点传送地址:一组接口(一般不属于不同节点)的标识符。送往一个多点传送地址的包将被传送到该地址标识的所有接口上
IPv6地址:ip地址形式之一
你去下载个六飞,这个软件可以ipv4转ipv6,但是下载速度还是没纯ipv6好的
ipv6的表示方式IPV6地址的表示采用16进制的表示方法。将128bit分为8组,每组16比特,用4个16进制数表示,各组之间用":"隔开,每组中最前面的0可以省略,但每组必须得有一个数。1、冒分十六进制表示法格式为 X:X:X:X:X:X:X:X,其中每个X代表16个bit,以十六进制显示,如下面这些:ip一:ABCD:EF01:2345:6789:ABCD:EF01:2345:6789ip二:FEDC:BA98:7654:3210:FEDC:BA98:7654:3210ip三:1080:0:0:0:8:800:200C:417A2、0位压缩表示法在某些情况下,一个IPv6地址中问可能包含很长的一段0,可以把连续的一段0压缩为“::”。但为保证地址解析的唯一性,地址中”::”只能出现一次,例如:1080:0:0:0:8:800:200C:417A =1080::8:800:200C:417AFF01:0:0:0:0:0:0:101=FF01::101FF01:0:0:0:0:0:0:1101 = FF01::11010:0:0:0:0:0:0:1 = ::10:0:0:0:0:0:0:0 = ::3、内嵌IPv4地址表示法网页链接为了实现IPv4-IPv6互通,IPv4地址会嵌入IPv6地址中,此时地址常表示为:X:X:X:X:X:X:d.d.d.d,也就是前6组用冒分十六进制表示,后二组用十进制表示,而最后32bit地址则使用IPv4的点分十进制表示,例如::192.168.0.1与就是一个典型的例子 。四、如何将ipv4转换为ipv6地址?上面我们提到了,ipv4地址要与ipv6地址互通,需要将ipv4转换为ipv6地址。举例:如果IPv4的一个地址为135.75.43.52,现有32位地址,那么如何转换为ipv6呢?1、非标准转换:只需要在ip地址前面6组共96位补充0即可,即0000:0000:0000:0000:0000:0000:135.75.43.52也就是::135.75.43.52(内嵌IPv4表示法)2、标准转换135.75.43.52 按十六进制算出即87.4B.2B.34,而87.4B.2B.34串地址一组还是8位,所以需要两组v4地址合成v6地址,再把前96位补零,它可以被转化为0000:0000:0000:0000:0000:0000:874B:2B34或者::874B:2B34。补充下:十进制如何转化为16进制?这里弱电君有必要补充下十进制如何转化为16进制,在ipv6时代,可能会经常需要用到。方法是:十进制数除以16,反向取余数,除到不能除为止。当然大家听到这个方法可能是一头雾水,我们具体来看下举例计算过程。例如10进制的ipv4地址:135.75.43.52 ,化成16进制的。为了方便大家了解原理,具体计算过程可以看下图:16进制的10、11、12、13、14、15分别用A、B、C、D、E、F来表示。所以十进制的135.75.43.52 最终得出的是十六进制87.4B.2B.34,转成ipv6就是::874B:2B34。当然也是可以通过工具直接转换。

ipv4与ipv6如何转换?计算方法是什么?
ipv4与ipv6不需要进行转换,因为为了实现IPv4-IPv6互通,IPv4地址会嵌入IPv6地址中,此时地址常表示为:X:X:X:X:X:X:d.d.d.d,前96b采用冒分十六进制表示,而最后32b地址则使用IPv4的点分十进制表示。计算方法:直接截取ipv6的后32b就是ipv4。扩展资料:IPv6与IPv4之间的过渡技术IPv6不可能立刻替代IPv4,因此在相当一段时间内IPv4和IPv6会共存在一个环境中。要提供平稳的转换过程,使得对现有的使用者影响最小,就需要有良好的转换机制。这个议题是IETF ngtrans工作小组的主要目标,有许多转换机制被提出,部分已被用于6Bone上。IETF推荐了双协议栈、隧道技术以及网络地址转换等转换机制:一、IPv6/IPv4双协议栈技术二、隧道技术三、网络地址转换技术网络地址转换(Network Address Translator,NAT)技术是将IPv4地址和IPv6地址分别看作内部地址和全局地址,或者相反。例如,内部的IPv4主机要和外部的IPv6主机通信时,在NAT服务器中将IPv4地址(相当于内部地址)变换成IPv6地址(相当于全局地址),服务器维护一个IPv4与IPv6地址的映射表。反之,当内部的IPv6主机和外部的IPv4主机进行通信时,则IPv6主机映射成内部地址,IPv4主机映射成全局地址。NAT技术可以解决IPv4主机和IPv6主机之间的互通问题 。参考资料:百度百科-IPv6
IPv4:是互联网协议的第四版,同时也是第一个被广泛使用,构成现今互联网技术的基石的协议;IPv6:是互联网工程任务组设计的用于替代现行版本IPv4的下一代IP协议;目前IP协议的版本号是IPv4,它的下一个版本就是IPv6。ipv4与ipv6地址如何转换的python解决办法源码如下:(需要用到twisted.python.compat及struct和python socket方法)import struct,socket#import twisted.python.compat #导入twisted.python.compat 更方便# ipv4数字地址def ipv4_to_string(ipv4):ipv4_n = socket.htonl(ipv4)data = struct.pack('I', ipv4_n)ipv4_string = socket.inet_ntop(socket.AF_INET, data)return ipv4_stringdef ipv4_from_string(ipv4_string):data = socket.inet_pton(socket.AF_INET, ipv4_string)ipv4_n = struct.unpack('I', data)ipv4 = socket.ntohl(ipv4_n[0])return ipv4def ipv4_readable2int(ipv4):return int(ipv4)def ipv4_int2readable(ipv4):return str(ipv4)# ipv6用四个整数(tuple或用,分开的字符串)表示def ipv6_to_string(ipv6):ipv6_n = (socket.htonl(ipv6[0]),socket.htonl(ipv6[1]),socket.htonl(ipv6[2]),socket.htonl(ipv6[3]))data = struct.pack('IIII', ipv6_n[0], ipv6_n[1], ipv6_n[2], ipv6_n[3])ipv6_string = socket.inet_ntop(socket.AF_INET6, data)return ipv6_stringdef ipv6_from_string(ipv6_string):data = socket.inet_pton(socket.AF_INET6, ipv6_string)ipv6_n = struct.unpack('IIII', data)ipv6 = (socket.ntohl(ipv6_n[0]),socket.ntohl(ipv6_n[1]),socket.ntohl(ipv6_n[2]),socket.ntohl(ipv6_n[3]))return ipv6def ipv6_tuple2readable(ipv6):return str(ipv6[0]) + ',' + str(ipv6[1]) + ',' + str(ipv6[2]) + ',' + str(ipv6[3])def ipv6_readable2tuple(ipv6):return tuple(ipv6.split(','))#win32 下实现 inet_pton 和 inet_ntodef inet_ntop(family, ipstr):if family== socket.AF_INET:return socket.inet_ntoa(ipstr)elif family== socket.AF_INET6:v6addr = ':'.join(('%02X%02X' % (ord(i), ord(j)))for i,j in zip(ipstr[::2], ipstr[1::2]))return v6addr#www.iplaypy.comdef inet_pton(family, addr):if family== socket.AF_INET:return socket.inet_aton(addr)elif family== socket.AF_INET6:if '.' in addr: # a v4 addrv4addr = addr[addr.rindex(':')+1:]v4addr = socket.inet_aton(v4addr)v4addr = map(lambda x: ('%02X' % ord(x)), v4addr)v4addr.insert(2, ':')newaddr = addr[:addr.rindex(':')+1] + ''.join(v4addr)return inet_pton(family, newaddr)dbyts = [0]* 8 # 8 groupsgrps = addr.split(':')for i,v in enumerate(grps):if v:dbyts[i] = int(v, 16)else:for j, w in enumerate(grps[::-1]):if w:dbyts[7-j] = int(w, 16)else:breakbreakreturn ''.join( (chr(i//256) + chr(i%256)) for i in dbyts)else:raise RuntimeError("What family?")IPv4的地址如何转换为IPv6的地址IPv4地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节),通常我们以10进制表示。例如192.168.1.1就是一个10进制的IPv4地址,如果用2进制表示,则为11000000 10101000 00000001 00000001这里设计的2进制与10进制的计算方法比较简单,这里就不再阐述。那么由IPv4的地址转换为IPv6的地址怎么转换呢?这里有2种表示方法:第一种比较简单的。例如还是IPv4的192.168.1.1 转换成IPv6的地址,则为::192.168.1.1 。就是在IPv4的地址前添加::即可,不需要经过计算。第二种标准的IPv6地址,需要经过计算。首先,需要将IPv4的地址转换成2进制的,然后再由2进制的数,每4位为一组,转换成16进制的,最后再转换为IPv6地址。举例说明,192.168.1.1,10进制表示为192.168.1.1,2进制表示为11000000 10101000 00000001 00000001,16进制表示为C0 A8 01 01,IPv6地址为0:0:0:0:0:0:C0A8:0101。下表会更加清晰。

本文由 在线网速测试 整理编辑,转载请注明出处。