精华内容
下载资源
问答
  • 封装和信息隐藏
    千次阅读
    2018-11-08 19:45:24

    为对象创建私用成员是任何面向对象语言中最基本和有用的特性之一。通过将一个方法或属性声明为私用的,可以让对象的实现细节对其他对象保密以降低对象之间的耦合程度,可以保持数据的完整性并对其修改方式加以约束。在代码有许多人参与设计的情况下,这也可以使代码更可靠、更易于调试。简而言之,封装是面向对象的设计的基石。
    尽管JavaScript是一种面向对象的语言,它并不具备用以将成员声明为公用或私用的任何内置机制。目前有几种办法可以用来创建具有公用、私用和特权方法的对象,它们各有优缺点。

    3.1 信息隐藏原则

    3.1.1 封装与信息隐藏

    可以把封装和信息隐藏视为同一个概念的两种表述。信息隐藏是目的,封装是达到这个目的的技术。
    封装可以被定义为对对象的内部数据表现形式和实现细节进行隐藏。要想访问封装过的对象中的数据,只有使用已定义的操作这一种办法。通过封装可以强制实施信息隐藏。许多面向对象语言都使用关键字来说明某些方法和属性应被隐藏。但在JavaScript中没有这样的关键字,我们将使用闭包的概念来创建只允许从对象内部访问的方法和属性。这比使用关键字的办法更复杂。

    3.1.2 接口扮演的角色

    在向其他对象隐藏信息的过程中接口是如何发挥作用的呢?
    接口提供了一份记载着可供公众访问的方法的契约。它定义了两个对象间可以具有的关系。只要接口不变,这个关系的双方都是可替换的。大多数情况下,你将发现对可以使用的方法加以记载会很有好处。不是有了接口就万事大吉,你应该避免公开未定义于接口中的方法。否则其他对象可能会对那些并不属于接口的方法产生依赖,这是不安全的。因为这些方法随时都可能发生改变或被删除,从而导致整个系统失灵。
    一个理想的软件系统应该为所有类定义接口。这些类只向外界提供它们实现的接口中规定的方法,任何别的方法都留作自用。其所有属性都是私有的,外界只能通过接口中定义的存取操作与之打交道。但实际的系统很少能真正达到这样的境界。优质的代码应尽量向这个目标靠拢,但又不能过于刻板,把那些并不需要这些特性的简单项目复杂化。

    3.2 创建对象的基本模式

    JavaScript创建对象的基本模式有3种

    1. 门户大开型,这是最简单的一种,但它只能提供公用成员。
    2. 使用下划线表示私用方法或属性。
    3. 使用闭包来创建真正的私用成员,这些成员只能通过一些特权方法访问。

    以Book为例,该类满足这样的需求:存储关于一本书的数据,并实现一个以HTML形式显示这些数据的方法。
    你只负责创建这个Book类,别人会创建并使用其实例。它会被这样使用:

    // Book (isbn, title, author)
    var theHobbit = new Book('0-395-07122-4', 'The Hobbit', 'J. R. R. Tolkien');
    theHobbit.display();//通过创建HTML element显示数据
    

    3.2.1 门户大开型对象

    用一个函数来做其构造器,它的所有属性和方法都是公开的、可访问的。这些公用属性需要使用this关键字来创建。

    var Book = function(isbn, title, author) {
    	if(isbn == undefined) throw new Error('Book constructor requires an isbn.');
    	this.isbn = isbn;
    	this.title = title || 'No title specified';
    	this.author = author || 'No author specified';
    };
    Book.prototype.display = function () {
    	...
    }
    

    好像提供了ISBN就可以查到书籍了,可是这里有一个最大的问题,你无法检验ISBN数据的完整性,而不完整的ISBN数据有可能导致display方法失灵。如果Book对象在创建的时候没有什么问题,那么在display时也能正常工作才对,但是由于没有进行完整性检查,就不一定了。下面的版本强化了对ISBN的检查。

    var Book = function(isbn, title, author) {
    	if(!this.checkIsbn(isbn)) throw new Error('Book: Invalid ISBN.');
    	this.isbn = isbn;
    	this.title = title || 'No title specified';
    	this.author = author || 'No author specified';
    }
    Book.prototype = {
    	checkIsbn: function(isbn) {
    		if(isbn == undefined || typeof isbn != 'string'){
    			return false;
    		}
    		isbn = isbn.replace(/-/,'');
    		if(isbn.length != 10 && isbn.length !=13) {
    			return false;
    		}
    		var sum = 0;
    		if(isbn.length === 10) {//10位的ISBN
    			if(!isbn.match(/^\d{9}/)) {
    				return false;
    			}
    			for(var i = 0; i < 9; i++) {
    				sum += isbn.charAt(i) * (10-i);
    			}
    			var checksum = sum % 11;
    			if(checksum === 10) checksum = 'X';
    			if(isbn.charAt(9) != checksum) {
    				return false;
    			}
    		}
    		else {//13位的ISBN
    			if(!isbn.match(/^\d{12}/)) {
    				return false;
    			}
    			for(var i = 0; i < 12; i++) {
    				sum += isbn.charAt(i) * ((i % 2 === 0) ? 1 : 3);
    			}
    			var checksum = sum % 10;
    			if(isbn.charAt(12) != checksum) {
    				return false;
    			}		
    		}
    		return true;
    	},
    	display: function() {
    		...
    	}
    };
    

    checkIsbn保证ISBN是一个具有正确的位数和校验和的字符串。这样在创建对象的时候可以对ISBN的有效性进行检查,这可以确保display方法能正常工作。

    但问题又来了,即使在构造的时候能对ISBN进行检验,如果后续其他程序员把其他值赋给isbn,这时就检验不了了,

    theHobbit.isbn = '978-0261103283';
    theHobbit.display();
    

    为了保护内部数据,为每一个属性都提供了取值器和赋值器方法。

    • 取值器方法用于获取属性值,通常以getAttributeName这种形式命名;
    • 赋值器方法用于设置属性值,通常以setAttributeName这种形式命名。

    通过使用赋值器,你可以在把一个新值真正赋给属性之前进行各种检验。

    var Publication = new Interface('Publication', ['getIsbn', 'setIsbn', 'getTitle', 'setTitle', 'getAuthor', 'setAuthor', 'display']);
    
    var Book = function(isbn, title, author) {
    	this.setIsbn(isbn);
    	this.setTitle(title);
    	this.setAuthor(author);
    }
    
    Book.prototype = {
    	checkIsbn: function(isbn) {
    		...
    	},
    	getIsbn: function() {
    		return this.isbn;
    	},
    	setIsbn: function(isbn) {
    		if(!this.checkIsbn()) throw new Error('Book: Invalid ISBN.');
    		this.isbn = isbn;
    	},
    	getTitle: function() {
    		return this.title;
    	},
    	setTitle: function(title) {
    		this.title = title || 'No title specified.';
    	},
    	getAuthor: function() {
    		return this.author;
    	},
    	setAuthor: function(author) {
    		this.author = author || 'No author specified.';
    	},
    	display: function() {
    		...
    	}
    };
    

    这是使用门户大开型对象创建方式所能得到的最好结果。

    这里明确定义了接口、一些对数据具有保护作用的取值器和赋值器方法,以及一些有效性检验方法。

    这里还是有一个漏洞,虽然我们为设置属性提供了赋值器方法,但那些属性仍然是公开的,可以被直接设置的,而在这种方案中却无法阻止这种行为。

    不过这种方法易于使用,创建这样的对象不要求你深入理解作用域或调用链的概念。由于所有方法和属性都是公开的,派生子类和进行单元测试也很容易。唯一的弊端在于无法保护内部数据,而且取值器和赋值器也引入了额外的代码。

    3.2.2 用命名规范区别私用成员

    从本质上来说,这种模式与门户大开型对象创建模式如出一辙,只不过在一些方法和属性的名称前加了下划线以示其私用性而已。这种方法可以解决上一种方法带来的问题:无法阻止其他程序员无意中绕过的所有检验步骤。

    var Book = function(isbn, title, author) {
    	this.setIsbn(isbn);
    	this.setTitle(title);
    	this.setAuthor(author);
    }
    
    Book.prototype = {
    	checkIsbn: function(isbn) {
    		...
    	},
    	getIsbn: function() {
    		return this._isbn;
    	},
    	setIsbn: function(isbn) {
    		if(!this.checkIsbn()) throw new Error('Book: Invalid ISBN.');
    		this._isbn = isbn;
    	},
    	getTitle: function() {
    		return this._title;
    	},
    	setTitle: function(title) {
    		this._title = title || 'No title specified.';
    	},
    	getAuthor: function() {
    		return this._author;
    	},
    	setAuthor: function(author) {
    		this._author = author || 'No author specified.';
    	},
    	display: function() {
    		...
    	}
    };
    

    这种命名规范也可以应用于方法,例如checkIson方法应该是类私有的方法:

    	_checkIsbn: function(isbn) {
    		...
    	},
    

    下划线的这种用法是一个众所周知的命名规范,它表明一个属性或方法仅供对象内部使用,直接访问它或设置它可能会导致意想不到的后果。这有助于防止程序员对它的无意使用,却不能防止对它的有意使用。

    这并不是真正可以用来隐藏对象内部数据的解决方法,它主要适用于非敏感性的内部方法和属性。

    3.2.3 作用域、嵌套函数和闭包

    在讨论真正的私用性方法和属性的实现技术之前,我们先花点时间解释一下这种技术背后的原理。
    在JavaScript中,只有函数具有作用域。也就是说,在一个函数内部声明的变量在函数外部无法访问。私用属性就其本质而言就是希望在对象外部无法访问的变量,所以为实现这种拒访性而求助于作用域这个概念是合乎情理的。

    定义在一个函数中的变量在该函数的内嵌函数中是可以访问的:

    function foo() {
    	var a = 10;
    	function bar() {
    		a *= 2;
    	}
    	bar();
    	return a;
    }
    foo();//20
    

    一个简单的闭包例子:

    function foo() {
    	var a = 10;
    	function bar() {
    		a *= 2;
    		return a;
    	}
    	return bar;
    }
    var baz = foo();
    baz(); // 20
    baz(); // 40
    baz(); // 80
    

    可以看到,函数是在foo外部被调用,但它依然能够访问a,这是因为JavaScript中的作用域是词法性的。函数是运行在定义它们的作用域中,而不是运行在调用它们的作用域中。所以,bar被定义在foo的作用域中,就能访问foo中定义的变量,即使foo的执行已经结束。

    3.2.4 用闭包实现私用成员

    var Book = function (newIsbn, newTitle, newAuthor) {
    	// Private attributes.
    	var isbn, title, author;
    
    	// Private method.
    	function checkIsbn(isbn) {
    		...
    	}
    
    	// Privileged methods.
    	this.getIsbn = function () {
    		return isbn;
    	};
    	this.setIsbn = function (newIsbn) {
    		if(!checkIsbn(newIsbn)) throw new Error('Book: Invalid ISBN.');
    		isbn = newIsbn;
    	};
    
    	this.getTitle = function () {
    		return title;
    	};
    	this.setTitle = function (newTitle) {
    		title = newTitle || 'No title specified';
    	};
    
    	this.getAuthor = function () {
    		return author;
    	};
    	this.setAuthor = function (newAuthor) {
    		author = newAuthor || 'No author specified';
    	};
    
    	// Constructor code.
    	this.setIsbn(newIsbn);
    	this.setTitle(newTitle);
    	this.setAuthor(newAuthor);
    };
    
    // Public, non-privileged methods.
    Book.prototype = {
    	display: function() {
    		...
    	}
    }
    

    代码解读:

    • 使用var声明的变量或方法是私有的,因为没有用this关键字,这意味着它们只存在于Book构造器中
    • 要访问这些私有的变量和方法,需在Book中使用this关键字声明方法,这些方法被称为特权方法(privileged method),它们是公用的方法,因为声明在Book内部,所以在对象外部可以访问到私用属性和方法。
    • 任何不需要直接访问私用属性的方法都可以在Book.prototype中声明。
    • 每生成一个新的对象实例都将为每一个私用方法和特权方法生成一个新的副本。这会比其他做法更耗内存。
    • 不利于派生子类,因为所派生出的子类不能访问超类的任何私用属性或方法。相比之下,在大多数语言中,子类都能访问超类的所有私用属性和方法。故在JavaScript中用闭包实现私用成员导致的派生问题被称为“继承破坏封装”

    3.3 更多高级对象创建模式

    前面学习了创建对象的3种基本模式,下面再对一些高级一点的模式做一个简介。

    3.3.1 静态方法和属性

    静态成员是在类的层次上操作的,而不是在实例的层次上操作。每个静态成员都只有一份。
    下面是添加了静态属性和方法的Book类:

    var Book = (function() {
    	// Private static attributes.
    	var numOfBooks = 0;
    
    	// Private static method.
    	function checkIsbn(isbn) {
    		...
    	}
    
    	// Return the constructor.
    	return function (newIsbn, newTitle, newAuthor) {
    		// Private attributes.
    		var isbn, title, author;
    	
    		// Private method.
    		function checkIsbn(isbn) {
    			...
    		}
    	
    		// Privileged methods.
    		this.getIsbn = function () {
    			return isbn;
    		};
    		this.setIsbn = function (newIsbn) {
    			if(!checkIsbn(newIsbn)) throw new Error('Book: Invalid ISBN.');
    			isbn = newIsbn;
    		};
    	
    		this.getTitle = function () {
    			return title;
    		};
    		this.setTitle = function (newTitle) {
    			title = newTitle || 'No title specified';
    		};
    	
    		this.getAuthor = function () {
    			return author;
    		};
    		this.setAuthor = function (newAuthor) {
    			author = newAuthor || 'No author specified';
    		};
    	
    		// Constructor code.
    		numOfBooks++;
    		if(numOfBooks > 50) throw new Error('Book: Only 50 instances of Book can be created.');
    		this.setIsbn(newIsbn);
    		this.setTitle(newTitle);
    		this.setAuthor(newAuthor);	
    	}
    })();
    
    // 创建Public static method.
    Book.convertToTitleCase = function(inputString) {
    	...
    };
    
    // Public, non-privileged methods.
    Book.prototype = {
    	display: function() {
    		...
    	}
    }
    

    这里创建了一个闭包,将构造器从原来的普通函数变成了一个内嵌函数,并且作为返回值赋给变量Book。外层的函数只是用于创建一个可以用来存放静态私用成员的闭包,这些静态私用成员不会为Book的每一个实例都创建一个新的副本。
    如何判断一个私用方法是否应该被设计为静态方法?
    看它是否需要访问任何实例数据。如果它不需要,则设计为静态方法会更有效率,因为它只会被创建一份。

    3.3.2 常量

    常量是一些不能被修改的变量。在JavaScript中,可以通过创建只有取值器而没有赋值器的私有变量来模仿常量。

    var Class = (function() {
    	// Constants (created as private static attributes.).
    	var UPPER_BOUND	= 100;
    	// Constructor.
    	var ctor = function (constructorArgument) {
    		...
    	};
    	// Privileged static method.
    	ctor.getUPPER_BOUND = function() {
    		return UPPER_BOUND;
    	};
    	...
    	// Return the constructor
    	return ctor;
    })();
    

    如果需要使用许多常量,但你不想为每个常量都创建一个取值器方法,那么可以创建一个通用的取值器方法,如下:

    var Class = (function() {
    	// Constants (created as private static attributes.).
    	var constants ={
    		UPPER_BOUND: 100,
    		LOWER_BOUND: -100
    	};
    	// Constructor.
    	var ctor = function (constructorArgument) {
    		...
    	};
    	// Privileged static method.
    	ctor.getConstant = function(name) {
    		return constants[name];
    	};
    	...
    	// Return the constructor
    	return ctor;
    })();
    Class.getConstant('UPPER_BOUND');
    

    3.3.3 单体和对象工厂

    单体模式和工厂模式也使用闭包来创建受保护的变量空间,后面部分会详细讨论这两种模式。在此简单介绍一下:

    • 单体模式使用一个由外层函数返回的对象字面量来公开特权成员,而私用成员则被保护性地封装在外层函数的作用域中。它使用的技术是:外层函数在定义之后立即执行,其结果被赋给一个变量。本章的例子中外层函数返回的都是一个函数,而单体模式返回的则是一个对象字面量。
    • 对象工厂也可以使用闭包来创建具有私用成员的对象。其最简形式就是一个类构造。

    3.4 封装之利

    要是在创建对象时不用操心闭包和特权方法,事情就会简单得多。那么,不厌其烦的隐藏实现细节究竟有什么好处?
    封装保护了内部数据的完整性。通过将数据的访问途径设置为取值器和赋值器这两个方法,可以获得对取值和赋值的完全控制。这可以减少其他函数所需的错误检查代码的数量,并确保数据不会处于无效状态。
    封装提高了对象的可重用性,使其在必要的时候可以被替换。使用私用变量也有助于避免命名空间冲突。
    封装还使你可以大幅改动对象的内部细节,而不会影响到其他部分的代码。总的来说,代码的修改变得更轻松,如果对象的内部数据都是公开的话,你不可能完全清楚代码的修改会带来什么结果。

    3.5 封装之弊

    私用方法很难进行单元测试。因为他们及其内部变量都是私用的,在对象外部无法访问到它们。要么通过使用公用方法来提供访问途径(这样一来就葬送了使用私用方法所带来的大多数好处),要么设法在对象内部定义并执行所有测试单元。最好的解决办法是只对公用方法进行单元测试。这是一种广为接受的处理方式。
    使用封装意味着不得不与复杂的作用域链打交道,而这会使错误调试变得更加困难。有时候会很难区分来自不同作用域的大批同名变量。这个问题不是经过封装的对象所特有的,但实现私用方法和属性所需的闭包会让它变得更复杂。
    过度封装也是一个潜在的问题。
    最大的问题在于JavaScript中实现封装的困难。JavaScript本来就是一门与多数面向对象语言大相径庭的语言,而封装技术设计的调用链和定义后立即执行的匿名函数等概念更是加大了学习难度。此外,封装技术的应用还使不熟悉特定模式的人难以理解既有代码。注释和程序文档可以提供一些帮助,但并不能完全解决这个问题。

    3.6 小结

    本章讨论了信息隐藏的概念以及如何用封装这种手段来实现它。因为JavaScript没有对封装提供内置的支持,所以其实现必须依赖于一些其他技术。本书后面的多数章节都依赖于这些基本技术,因此你得好好品味一下本节的内容。只要理解了JavaScript中作用域的特点,你就能模仿出各种面向对象的技术。

    更多相关内容
  • C++ 封装 & 信息隐藏

    千次阅读 多人点赞 2021-05-02 14:02:39
    C++ 封装 & 信息隐藏简介

    概述

    封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念. 这样能避免受到外界干扰和误用.
    在这里插入图片描述
    数据隐藏包括数据封装和数据抽象两部分. 数据封装是一种把数据和操作数据的函数捆绑在一起的机制. 数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制.
    在这里插入图片描述

    类的公用接口

    C++ 通过类来实现封装性, 把数据和与这些数据有关的操作封装在一个类中. 在声明了一个类以后, 用户主要是通过调用公用的成员函数来实现类提供的功能, 称为消息传递.

    公用成员函数是用户使用类的公用接口 (public interface), 或者说是类的对外接口. 在类外不能直接访问私有数据成员, 但可以通过调用公用成员函数来引用甚至修改私有数据成员.

    在这里插入图片描述

    类的私有实现

    用户不必关系这些功能实现的细节, 而只需要知道调用哪个函数会得到什么结果, 实现什么功能即可. 通过成员函数对数据成员进行操作称为类的实现. 实现的细节对用户是隐蔽的. (信息隐藏)

    类中被操作的数据是私有的, 实现的细节对用户是隐蔽的. 这称为私有实现. (private implementation)
    在这里插入图片描述
    类的公用接口与私有实现的分离形成了信息隐蔽. 将接口与实现分离是软件工程的一个最基本的原则.

    优点:

    1. 如果想扩充累的功能, 只需要修改本类中有关的数据成员和它有关的成员函数. 程序中类外的部分可以不必修改
    2. 如果在编译时发现类中的数据读写有错, 不必检查整个程序. 只需检查本类中访问这些数据的少数成员函数

    方法与消息

    方法 (method) 指类的成员函数在面向对象程序理论中被称为方法, 是指对数据的操作. 一个 “方法” 对应一种操作. 只有被声明为公用的方法才能被外界所激活.

    消息指对公用函数的调用. 外界是通过发 “消息” 来激活有关方法的. 调用对象的成员函数, 就是向对象发出的一个 “消息”. 通知它执行其中的方法.

    面向对象的特点:

    1. 封装性: 各个对象间相对独立
    2. 抽象性: 类是对象的抽象, 对象是类的实例
    3. 继承性: 解决重用问题
    4. 多态性: 由继承产生的相关的不同的类. 其对象对同一消息会做出不同的响应
    展开全文
  • 信息隐藏技术

    千次阅读 2021-06-02 21:45:34
    信息隐藏是将秘密信息隐藏在另一非机密的载体信息中,通过公共信道进行传递。秘密信息被隐藏后,攻击者无法判断载体信息中是否隐藏了秘密信息,也无法从载体信息中提取或去除所隐藏的秘密信息。信息隐藏技术研究的内容...
    • 信息隐藏(Information Hiding)作为一门新兴的交叉学科,伴随着信息和网络技术的飞速发展,在隐蔽通信、数字版权保护等方面起着越来越重要的作用。信息隐藏是将秘密信息隐藏在另一非机密的载体信息中,通过公共信道进行传递。秘密信息被隐藏后,攻击者无法判断载体信息中是否隐藏了秘密信息,也无法从载体信息中提取或去除所隐藏的秘密信息。信息隐藏技术研究的内容包括信息隐藏算法、数字水印、隐通道技术和匿名通信技术等。

    1. 传统的信息隐藏技术 :

    1. 技术性的隐写术——隐形墨水、录音回声等
    2. 语言学中的隐写术——藏头诗等
    3. 用于版权保护的隐写术——水印等

    2. 信息隐藏技术主要由下述两部分组成:

    • (1) 信息嵌入算法(编码器),它利用密钥来实现秘密信息的隐藏。
    • (2) 信息提取算法(检测器),它利用密钥从隐秘载体中检测并恢复出秘密信息。在密钥未知的前提下,第三者很难从隐秘载体中得到或删除甚至发现秘密信息。

     

     3. 信息隐藏的分类:

     法比安对信息隐藏的分类:

     根据秘钥的不同,信息隐藏可以分为三类:

     

    4. 信息隐藏的特性:

     

    与传统的加密方式不同的是,信息隐藏的目的在于保证隐藏数据不被未授权的第三方探知和侵犯,保证隐藏的信息在经历各种环境变故和操作之后不受破坏。因此,信息隐藏技术必须考虑正常的信息操作造成的威胁,使秘密信息对正常的数据操作,如通常的信号变换或数据压缩等操作具有免疫能力。根据信息隐藏的目的和技术要求,它存在以下5个特性。

    • (1) 安全性(security)。衡量一个信息隐藏系统的安全性,要从系统自身算法的安全性和可能受到的攻击两方面来进行分析。攻破一个信息隐藏系统可分为3个层次:证明隐藏信息的存在、提取隐藏信息和破坏隐藏信息。如果一个攻击者能够证明一个隐藏信息的存在,那么这个系统就已经不安全了。安全性是指信息隐藏算法有较强的抗攻击能力,它能够承受一定的人为的攻击而使隐藏信息不会被破坏。
    • (2) 鲁棒性(robustness)。除了主动攻击者对伪装对象的破坏以外,伪装对象在传递过程中也可能受到非恶意的修改,如图像传输时,为了适应信息的带宽,需要对图像进行压缩编码,还可能会对图像进行平滑、滤波和变换处理,声音的滤波、多媒体信号的格式转换等,这些正常的处理都有可能导致隐藏信息的丢失。信息隐藏系统的鲁棒性是指抗拒因伪装对象的某种改动而导致隐藏信息丢失的能力。所谓改动,包括传输过程中的信道噪声、滤波操作、重采样、有损编码压缩、D/A或A/D转换等。
    • (3) 不可检测性(undetectability)。不可检测性是指隐蔽载体与原始载体具有一致的特性,如具有一致的统计噪声分布,以便使非法拦截者无法判断是否藏有隐秘信息。
    • (4) 透明性(invisibility)。透明性是指利用人类视觉系统或听觉系统属性,经过一系列隐藏处理,目标数据必须没有明显的降质现象,而隐藏的数据无法被看见或听见。
    • (5) 自恢复性(self-recovery)。经过一些操作或变换后,可能使原图产生较大的破坏,如果只从留下的片段数据仍能恢复隐藏信号,而且恢复过程不需要宿主信号,这就是所谓的自恢复性。

     5. 信息隐藏的算法:

    根据载体的不同,信息隐藏可以分为图像、视频、音频、文本和其他各类数据的信息隐藏。在不同的载体中,信息隐藏的方法有所不同,需要根据载体的特征选择合适的隐藏算法。例如,图像、视频和音频中的信息隐藏利用了人的感官对于这些载体的冗余度来隐藏信息;而文本或其他各类数据需要从另外一些角度来设计隐藏方案。因此,一种很自然的想法是用秘密信息替代伪装载体中的冗余部分,替换技术是最直观的一种隐藏算法,也称为空间域算法。除此之外,对图像进行变换也是信息隐藏常用的一种手段,称为变换域算法。

    1. 图像是由很多像素点组成的,对二值图像来说,每个像素点用八位来表示,将像素最低位替换成秘密信息,人眼难以察觉。
    2. 空间域算法
    3.  变换(频)域算法:空间域算法的最大缺点是鲁棒性差,很难抵抗包括有损压缩、低通滤波等在内的各种攻击。另外,空间域中信息隐藏算法只能嵌人很小的数据量。图像的频域算法是指对图像数据进行某种变换,这种方法可以嵌人大量的比特而不引起可察觉的降质,当选择改变中频或低频分量(DCT变换除去直流分量)来嵌人信息时,健壮性可以大大提高。常用的频域信息隐藏算法有DFT(离散傅里叶变换) .DCT(离散余弦变换)和DWT(离散小波变换)。
       

     6. 数字水印:

     数字水印类似于信息隐藏,它也是在数字化的信息载体(指多媒体作品)中嵌人不明显的记号(也称为标识或水印)隐藏起来,被嵌人的信息包括作品的版权所有者、发行者、购买者、作者的序列号、日期和有特殊意义的文本等,但目的不是为了隐藏或传递这些信息,而是在发现盗版或发生知识产权纠纷时,用来证明数字作品的来源、版本、原作者、拥有者、发行人及合法使用人等。通常被嵌入的标识是不可见或不可观察的,它与源数据紧密结合并隐藏其中,成为源数据不可分离的一部分,并可以经历一些不破坏源数据的使用价值的操作而存活下来。这样的标识可以通过计算机操作被检测或者被提取出来。显而易见,数字水印是数字化的多媒体作品版权保护的关键技术之一,也是信息隐藏的重要分支。

     基本原理:

     7. 隐通道技术:

     概念:

     

     

     

     分类:

    根据隐通道的形成,隐通道可分为:

    • 存储隐通道(storage covert channels)
    • 时间隐通道( timing covert channels);

    根据隐通道是否存在噪声,隐通道可分为:

    • 噪声隐通道(noisycovert channels)
    • 无噪声隐通道(noiselesscovert channels);

    根据隐通道所涉及的同步变量或信息的个数,隐通道可分为:

    • 聚集隐通道(aggregated covert channels)
    • 和非聚集隐通道( noaggregated covert channels)
       

    隐通道分析方法:

    1. 信息流分析方法
    2. 非干扰分析方法
    3. 共享资源矩阵法

    8. 匿名通信技术:

    通俗地讲,匿名通信就是指不能确定通信方身份(包括双方的通信关系)的通信技术,它保护通信实体的身份。严格地讲,匿名通信是指通过一定的方法将业务流中的通信关系加以隐藏,使窃听者无法直接获知或推知双方的通信关系或通信双方身份的一种通信技术。匿名通信的重要目的就是隐藏通信双方的身份或通信关系,从而实现对网络用户个人通信隐私及对涉密通信的更好的保护。
     

    分类:

     

    信息安全与技术(第二版)

    展开全文
  • 走进信息隐藏的世界,全面讲解信息隐藏——第1节:信息隐藏技术简介 专栏题记:奥斯卡优秀电影《美丽心灵》里面有讲述一位优秀数学家为政府破译敌国通讯的情节,如电影所讲,现实中也有着类似的情节,在我们的生活...

    走进信息隐藏的世界,全面讲解信息隐藏——第1节:信息隐藏技术简介


    专栏题记:奥斯卡优秀电影《美丽心灵》里面有讲述一位优秀数学家为政府破译敌国通讯的情节,如电影所讲,现实中也有着类似的情节,在我们的生活中,我们所看过的图片、视频和游览过的网页,也许就隐藏着他人需要传输的秘密信息(是不是有点恐怖,差一点成为帮凶了),这就是信息隐藏!由于应用场景一般比较神秘,导致很多人其实都不太了解信息隐藏技术。由于国家越来越重视网络信息的安全,现在也是有越来越多的研究人员进行着这方面的研究工作。本人也是其中一位非常平凡的研究人员,笔者抱着学习和分享的态度,希望略尽绵薄之力让大家对信息隐藏技术不再陌生,同时慢慢掌握如何进行信息隐藏的技术。接下来本人会不定时更新信息隐藏技术的相关原理和关键技术实现过程,同时会提供程序代码给大家学习,也欢迎有志之士可以和我一同创建学习平台,也可以在评论下建议下一节希望学习的研究内容。谢谢!


    目录

    1、信息隐藏概念

    2、信息隐藏系统模型

    3、信息隐藏技术的分支简介

    4、信息隐藏技术的特性和要求

    5、信息隐藏关键技术

    6、信息隐藏的应用实例

    案例一:信息隐藏技术在电子商务中的应用

    案例二:信息隐藏技术在网络战中的运用



    • 信息隐藏概念

           信息隐藏也称数据隐藏,信息隐藏技术是指在不对载体数据产生可察觉影响的前提下,将密信数据隐藏到载体中实现隐蔽通讯的技术。是集多学科理论与技术于一身的新兴技术领域。信息隐藏技术主要是指将特定的信息嵌入数字化宿主信息(如文本,数字化的声音、图像、视频信号等)中,信息隐藏的目的不在于限制正常的信息存取和访问,而在于保证隐藏的信息不引起监控者的注意和重视,从而减少被攻击的可能性,在此基础上再使用密码术来加强隐藏信息的安全性,因此信息隐藏比信息加密更为安全。应该注意到,密码术和信息隐藏技术不是互相矛盾、互相竞争的技术,而是相互补充的技术,他们的区别在于应用的场合不同,对算法的要求不同,但可能在实际应用中需要互相配合。特定的信息一般就是保密信息,信息隐藏的历史可以追溯到古老的隐写术,但推动了信息隐藏的理论和技术研究始于1996年在剑桥大学召开的国际第一届信息隐藏研究会,之后国际机构在信息隐藏领域中的隐写术、数字水印、版权标识,可视密码学等方面取得大量成果。


    • 信息隐藏系统模型

           广义的信息隐藏系统模型主要有四部分组成:(1)信息嵌入,即利用嵌入秘钥来实现嵌入对象的隐藏过程;(2)信息提取,即利用提取秘钥从隐藏对象或可能经过修改的隐藏对象中提取或恢复出嵌入对象,在提取时,原始的载体对象可能需要参与也可能不需要参与;(3)秘钥生成,根据安全参数生成嵌入秘钥和提取秘钥;(4)隐藏分析,隐藏对象在传输过程中可能会被隐藏分析者截获并进行处理。信息隐藏系统模型如下图所示:

           在信息隐藏系统模型中,在嵌入过程中我们使用嵌入密钥将嵌入对象嵌入掩护对象中,生成隐藏对象,如下图将一个txt的文本嵌入到一张JPEG的图像中。嵌入对象和掩护对象可以是文本、图像或音频等等。在我们没有使用工具进行分析时,我们觉得掩护对象与隐藏对象几乎没有差别,这就是信息隐藏概念中所说的“利用人类感觉器官的不敏感性”。隐藏对象在信道中进行传输,在传输的过程中,有可能会遭到隐藏分析者的攻击,隐藏分析者的目标在于检测出隐藏对象、查明被嵌入对象、向第三方证明消息被嵌入、删除被嵌入对象、阻拦等。其中前三个目标通常可以由被动观察完成,称为被动攻击,后两个目标通常可以由主动攻击实现。提取过程则是在提取密钥的参与下从所接收到的隐藏对象中提取出嵌入对象,如将上述txt文件从JPG的图像中提取出来。有些提取过程并不需要掩护对象的参与,这样的系统称为盲隐藏技术,而需要掩护对象参与的系统则称为非盲隐藏技术。


    • 信息隐藏技术的分支简介

           作为信息安全领域的一个重要组成部分,信息隐藏技术已成为信息安全领域中一个既具有研究价值、同时又极具挑战性的热门课题,信息隐藏技术的分支主要包括:隐写术、数字水印、数字指纹、隐蔽信道、阈下信道、低截获概率通信和匿名通信等等。其分类示意图如下图所示:


    • 信息隐藏技术的特性和要求

           信息隐藏不同于传统的加密,因为其目的不在于限制正常的资料存取,而在于保证隐藏数据不被发现。因此,信息隐藏技术必须考虑正常的信息操作所造成的威胁,即要使机密数据对正常的数据操作技术具有免疫力。根据信息隐藏的不同目的和技术要求,该技术的存在以下特性和要求:

    1. 透明性或不可感知性:利用人类视觉系统或人类听觉系统属性,经过一系列的隐藏处理,使得载体对象没有明显的降质现象,如LSB算法等。当然,有些场合可能需要使用可见水印,例如某些版权维护的场合。
    2. 鲁棒性:指不因隐藏对象通过某些常用操作而导致嵌入对象丢失的能力。这里的常用操作包括滤波操作、有损压缩、几何变换、D/A或A/D等。
    3. 安全性:指算法具有较强的抗恶意攻击能力。
    4. 不可检测性:指载体数据嵌入数据后无明显改变,至少肉眼看不出变化

    • 信息隐藏关键技术

      近年来,信息隐藏技术的研究取得了很大的进步,已经提出了各种各样的隐藏算法。关键的信息隐藏技术有如下几种。

        (1)替换技术

        所谓替换技术,就是试图用秘密信息比特替换掉伪装载体中不重要的部分,以达到对秘密信息进行编码的目的。替换技术包括最低比特位替换、伪随机替换、载体区域的奇偶校验位替换和基于调色板的图像替换等。替换技术是在空间域进行的一种操作,通过选择合适的伪装载体和适当的嵌入区域,能够有效地嵌入秘密信息比特,同时又可保证数据的失真度在人的视觉允许范围内。

        已经提出的各种算法大都给出了其实现思想,如对于基于调色板的图像格式,可操作其调色板来嵌入信息,也可以利用它的量化值来隐藏秘密信息,因此该技术在数据伪装中得到了广泛的应用。

        替换技术算法简单,容易实现,但是鲁棒性很差,不能抵抗图像尺寸变化、压缩等一些基本的攻击,因此在数字水印领域中一般很少使用。

        (2)变换技术

        大部分信息隐藏算法都是在变换域进行的,其变换技术包括离散傅里叶变换(DFT)、离散余弦变换(DFT)、离散小波变换(DWT)和离散哈达玛特变换(DHT)等。这些变换技术都有各自的特点。

        DFT在信号处理中有着广泛应用,在信息隐藏领域也同样得到了应用。它将图像分割成多个感觉频段,然后选择合适部分来嵌入秘密信息。D CT使空间域的能量重新分布,从而降低了图像的相关性。在DCT域中嵌入信息的方法,通常是在一个图像块中调整两个(或多个)DCT系数的相对大小。DWT是对图像的一种多尺度、空间频率分解,即将输入信号分解为低分辨率参考信号和一系列细节信号。在一个尺度下,参考信号和细节信号包含了完全恢复上一尺度下信号的全部信息。

        (3)扩频技术

        当对伪装对象进行过滤操作时可能会消除秘密信息,解决的方法就是重复编码,即扩展隐藏信息。在整个伪装载体中多次嵌入一个比特,使得隐藏信息在过滤后仍能保留下来,这种方法虽然传输效率不高,但却具有较好的健壮性。扩频技术一般是使用比发送的信息数据速率高许多倍的伪随机码,将载有信息数据的基带信号频谱进行扩展,形成宽带低功率谱密度信号。最典型的扩频技术,为直序扩频和跳频扩频。直序扩频是在发端直接用具有高码率的扩频编码去扩展信号的频谱,而在接收端用相同的扩频编码解扩,将扩频信号还原为原始信号。跳频扩频是在发端将信息码序列与扩频码序列组合,然后按照不同的码字去控制频率合成器,使输出频率根据码字的改变而改变,形成频率的跳变;在接收端为了解跳频信号,要用与发端完全相同的本地扩频码发生器去控制本地频率合成器,从中恢复出原始信息


    • 信息隐藏的应用实例

    案例一:信息隐藏技术在电子商务中的应用

      目前信息隐藏技术在电子商务中的应用主要体现在以下几个方面:

      1.数据保密

      在具体电子商务活动中,数据在Internet上进行传输一定要防止非授权用户截获并使用,如敏感信息,谈判双方的秘密协议合同网上银行交易中的敏感数据信息,重要文件的数字签名和个人隐私等等。另外,还可以对一些不愿为别人所知道的内容使用信息隐藏的方式进行隐藏存储。

      2.数据的不可抵赖性

      在网上交易中,交易双方的任何一方不能抵赖自己曾经做出的行为,也不能否认曾经接收到的对方的信息,这是交易系统中的一个重要环节。这可以使用信息隐藏技术中的水印技术,在交易体系的任何一方发送或接收信息时,将各自的特征标记以水印的形式加入到传递的信息中,这咱水印应是不能被去除的,可达到确认其行为的目的。

      3.防伪

      商务活动中的各种票据的防伪也是信息隐藏技术的用武之地。在数字票据中隐藏的水印经过打印后仍然存在,可以通过再扫描回数字形式,提取防伪水印,以证实票据的真实性。

      4.数据的完整性

      对于数据完整性的验证是要确认数据在网上传输或存储过程中并没有被窜改,可通过使用脆弱水印技术保护的媒体一旦被窜改就会破坏水印,从而很容易被识别。

    案例二:信息隐藏技术在网络战中的运用[2]

      信息隐藏之所以比密码加密的方法进行保密通信具有更大优势,是因为以信息隐藏方式实现隐蔽通信,除通信双方以外的任何第三方并不知道秘密通信这个事实的存在,这就较之单纯的密码加密更多了一层保护,使得网络加密机制从“看不懂”变为“看不见”,以不至成为好事者攻击的目标。

      (1)数据保密

      在因特网上防止非授权用户截获并使用传输的一些秘密数据,是网络安全的一个重要内容。信息隐藏技术在军事上的应用,可以将一些不愿为人所知的重要标识信息用信息隐藏的方式进行隐蔽存储,像军事地图中标明的军备部署、打击目标,卫星遥感图像的拍摄日期、经纬度等等,都可用隐藏标记的方法使其以不可见的形式隐藏起来,只有掌握识别软件的人才能读出标记所在。

      (2)数据保护

      数据保护主要是保证传输信息的完整性。由于隐藏的信息是被藏在宿主图像等媒体的内容中,而不是文件头等处,因而不会因格式的变换而遭到破坏。同时隐藏的信息具有很强的对抗非法探测和非法破解的能力,可以对数据起到安全保护的作用。对于数据完整性的验证是要确认数据在网上传输或存储过程中并没有被窜改。通过使用脆弱水印技术保护的媒体一旦被窜改就会破坏水印,从而很容易被识别。

      (3)数据免疫

      所谓免疫是指不因宿主文件经历了某些变化或处理而导致隐藏信息丢失的能力。某些变化和处理包括:传输过程中的信道噪声干扰,过滤操作,再取样,再量化,数/模、模/数转换,无损、有损压缩,剪切,位移等。


    作者:Daniel
    来源:CSDN 
    版权声明:本文为原创文章,转载请附上博文链接:
    https://blog.csdn.net/qq_26464039/article/details/85779870


    展开全文
  • JSP的9个隐藏对象

    千次阅读 2018-05-21 16:22:11
    大家好,我是IT修真院,一枚正直纯洁善良的如刚入门的Java程序员,今天跟大家分享一下修真院官网JAVA任务六,深度思考中的知识点————JSP的9个隐式对象?...2.通过Web容器实现和管理 3.所有JSP...
  • 信息隐藏技术综述-学习笔记

    千次阅读 2022-04-01 12:35:17
    文章目录信息隐藏技术综述@[toc]一、什么是信息隐藏二、信息隐藏基本原理2.1信息隐藏的分类2.2信息隐藏的特性2.3信息隐藏的基本模型2.4信息隐藏的关键技术2.4.1空域法2.4.2变换域法2.4.3信道隐藏三、信息隐藏的应用...
  • 信息隐藏基本原理

    千次阅读 2021-04-08 10:23:04
    一些名词 A打算秘密传递一些信息给B...实现信息隐藏的基本要求 C正常且不会引起怀疑。 C’与C无法区分,无论是从感官上还是从计算机分析上。 不可视通信的安全性取决于第三方有没有能力将载体对象和伪装对象区别开来。
  • JAVA 面向对象 隐藏和封装

    千次阅读 2016-07-22 22:25:11
    在前面程序中,经常出现通过某个对象直接访问其成员变量的情况. 这可能引起一些潜在问题,比如将某个 Person 的 age 成员变量直接设为 1000. 这在语法上没有任何问题, 但显然违背了当前的自然规律. 人怎么可能活...
  • 好的类接口就像是冰山的尖儿一样,让类的大部分内容都不会暴露出来什么是信息隐藏信息隐藏指在设计和确定模块时,使得一个模块内包含的... 信息隐藏式结构程序设计与面向对象设计的基础之一。在面向对象设计中,它又
  • ----------------------- EL表达式的内置对象param参数隐藏对象------------------------------- EL内置对象 在EL表达式中,无需创建就可以使用的对象称之为EL隐藏(隐含、内置)对象。在EL中一共有11个隐藏对象,...
  • 空域信息隐藏算法(完成基于LSB的图像信息隐藏

    千次阅读 热门讨论 2019-04-07 19:57:49
    最近在上信息隐藏,做一个记录 一,实验要求 (1)了解信息隐藏算法的分类方式和分类依据 (2)理解空域信息隐藏算法的基本思想 (3)掌握最低有效位算法原理 (4)完成基于LSB的图像信息隐藏 二、实验内容 载体图像...
  • JSP之九大隐藏对象

    千次阅读 2015-06-12 15:55:11
    jsp内置对象(隐藏对象):不加声明和创建就可以在jsp页面脚本中使用的成员对象。内置对象类型作用域requestjavax.servlet....
  • 面向对象基本概念

    万次阅读 多人点赞 2019-02-06 21:56:15
    通过一个简单的外部接口与外界发生关系,对象对象之间通过消息进行通信。程序流程由用户在使用中决定。对象即为人对各种具体物体抽象后的一个概念,人们每天都要接触各种各样的对象,如手机就是一个对象。 面向...
  • 通过表单隐藏域向后台传值

    万次阅读 2019-03-28 17:39:05
    隐藏域】隐藏域是指在页面中对于用户是不可见的,在表单中插入隐藏域的目的在于收集或发送信息,以利于被处理表单的程序所使用。浏览者单击发送按钮发送表单的时候,隐藏域的信息也被一起发送到服务器。 代码...
  • 面向对象(隐藏和封装)

    千次阅读 2016-01-12 15:33:10
    合成存取方法面向对象(隐藏和封装)理解封装封装是面向对象程序语言对客观世界的模拟,在客观世界中对象的成员变量(用于描述对象的状态数据)都被隐藏对象内部,外部无法直接操作和修改。 对一个类或对象实现良好的...
  • C++隐藏的概念(例子解析)

    千次阅读 热门讨论 2018-06-01 18:33:09
    所谓的隐藏,指的是派生类类型的对象、指针、引用访问基类和派生类都有的同名函数时,访问的是派生类的函数,即隐藏了基类的同名函数。隐藏规则的底层原因其实是C++的名字解析过程。在继承机制下,派生类的类域被...
  • C++面向对象程序设计 面向对象编程

    万次阅读 多人点赞 2018-09-12 22:39:50
    1.1 面向过程的编程风格与面向对象的编程风格 C语言是面向过程语言,也称为命令型语言,面向过程...模块化的组织方式:将整个系统分解为若干模块,模块之间通过接口传递信息,模块划分应尽可能高内聚,低耦合。 ...
  • 音频信息隐藏技术研究

    千次阅读 2013-11-16 10:46:09
    与此不同,信息隐藏作为近年迅速发展起来的一种保密通信技术,它首先将待传输信息嵌入到诸如音频、视频、文件等载体中,使得非法第三方不易觉察到秘密信息的存在,然后通过携密载体的传送,实现秘密信息的保密传输。...
  • JQuery中easyui获取tab页对象以及获取获取tab页对象下的iframe对象和指定tab页对象隐藏 $('#mytabs').tabs( {  onSelect : function() {  var tab = $('#mytabs').tabs('getSelected');  zgoto(tab.panel('...
  • java面向对象

    万次阅读 多人点赞 2018-08-21 16:51:59
    面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程强调的是功能、行为 面向对象:将功能封装进对象,强调具备了功能的对象 面向对象是基于面向过程的 面向过程例子: ...
  • demo.go(通过func类型变量调用对象的方法,隐藏方法接收者): package main import "fmt" // 定义类 type Student struct { name string age int } // 定义类的方法 func (stu *Student)EditStu(name ...
  • java面向对象简介

    千次阅读 多人点赞 2021-11-06 13:59:14
    (1)可以通过对类的成员设置一定的访问权限,实现类中成员的信息隐藏。 private:类中限定为private的成员,只能被这个类本身访问。 default:类中不加任何访问权限限定的成员属于缺省的(default)访问状态,可以...
  • Unity 游戏物体的显示隐藏以及Time类

    千次阅读 2017-08-08 16:11:33
    组件的激活和隐藏: 使用渲染器(Renderer)中的enable属性: public class Demo4 : MonoBehaviour { public MeshRenderer rander; //在面板中拖拽赋值 void Update () { if (Input.GetMouseButtonDown(0...
  • 深入理解Python中的面向对象

    万次阅读 多人点赞 2017-06-12 06:42:41
    面向过程与面向对象的对比 id、type和value的讲解 类和对象的概念 初始化构造函数__init__的作用 self关键字的使用 继承的概念 组合的概念 接口的概念 抽象类的概念 1、面向过程与面向对象的对比面向过程的程序设计...
  • js面向对象理解

    万次阅读 多人点赞 2019-05-13 21:25:29
    面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。但是,ECMAScript 没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。 js(如果没有作特殊说明,本文...
  • Java是一门面向对象的程序设计语言

    千次阅读 2019-04-13 10:07:11
    1、什么是程序设计? 程序设计是对复杂性的管理,待解决问题的复杂性,以及用来...抽象出要解决的问题,通过编程语言让计算机实现对应的功能。 2、什么是编程语言? 编程语言之于计算机,类似英语对于美国人。...
  • 面向过程是一种以过程为中心的编程思想,其原理就是将问题分解成一个一个详细的步骤,然后通过函数实现每一个步骤,并依次调用。面向过程我们所关心的是解决一个问题的步骤,举个例子,汽车发动、汽车熄火,这是两个...
  • 第二章 隐写术 隐写术概念:将秘密信息嵌入到看上去普通的信息中进行传 送,以防止第三方检测出秘密信息 ...除了试图隐藏信息的内容,更进一步试图隐藏 通信事件本身的存在性 隐写系统的性能评价 透...
  • Power BI 学习(5)报表中视觉对象元素 在 Power BI Desktop 中,可以使用视觉对象元素(如壁纸和改进的视觉对象标头)来实现可视化效果,进而增强报表...将壁纸应用到报表,以此背景可以增强或突出显示想要通过数...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 371,549
精华内容 148,619
关键字:

信息隐藏是通过对象的